聊聊微服务认证之Oauth2
聊聊微服务认证之Oauth2
Oauth2是基于token的认证方式,它打通了web端和app端的统一认证,认证数据不需要存储在服务端,客户端只需要携带token就可以实现认证
这里说一下Oauth2的认证流程:
- 首先客户端会向资源拥有者发起请求授权,例如微信
- 然后资源拥有者进行确认授权,例如输入微信用户名密码后点击确认授权
- 这时客户端收到授权许可之后就会向认证服务器发起请求,申请令牌
- 认证服务器收到请求之后生成token给客户端
- 然后客户端携带token信息来访问资源服务器,这里比如获取微信昵称等等信息
- 资源服务器会先调用认证服务器验证token是否有效
- 资源服务器将资源返回给客户端,也就是把微信信息
一般情况下会有网关,客户端会先请求网关,网关调用认证服务器获取token信息,然后服务携带token信息调用具体服务,服务获取到token后调用认证服务器校验token有效性,如果有效就返回信息
把业务服务器变成资源服务器:
继承ResourceServerConfigurerAdapter类,并使用@EnableResourceServer注解表示开启资源服务的功能,重写两个configure()方法:
定义哪些方法需要放行不需要认证,哪些方法需要认证
public void configure(HttpSecurity httpSecurity) {
httpSecurity.headers().frameOptions().disable();
ExpressionUrlAuthorizationConfigurer<HttpSecurity>
.ExpressionInterceptUrlRegistry registry = httpSecurity
.authorizeRequests();
log.info(registry.toString() + "放行的url----->" + urls.toString());
urls.forEach(url -> registry.antMatchers(url).permitAll());
registry.anyRequest().authenticated()
.and().csrf().disable();
}
这里是除了urls中的放行,其他都需要认证
定义资源服务器向认证服务器发起请求,进行token校验
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId("autodeliver");
RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
remoteTokenServices.setCheckTokenEndpointUrl("http://localhost:9999/oauth/check_token");
remoteTokenServices.setClientId("xiepanpan");
remoteTokenServices.setClientSecret("123456");
resources.tokenServices(remoteTokenServices);
}
创建RemoteTokenServices,设置client secret 进行校验token
搭建认证服务器
- 继承AuthorizationServerConfigurerAdapter类来定义认证服务器配置类,类上添加@EnableAuthorizationServer注解,表示开启认证服务器,然后重写三个configure()方法
public void configure(ClientDetailsServiceConfigurer clients) {
TopeClientDetailsService clientDetailsService = new TopeClientDetailsService(dataSource);
clients.withClientDetails(clientDetailsService);
}
这个configure()是用来配置客户端详情的,包括client_id secret resourceid 认证类型、授权范围等信息,这里是可以从数据库中查询客户端详情,TopeClientDetailsService继承了JdbcClientDetailsService
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancer())
.userDetailsService(userDetailsService)
.authenticationManager(authenticationManager)
.reuseRefreshTokens(false)
.pathMapping("/oauth/confirm_access", "/token/confirm_access")
.exceptionTranslator(new TopeWebResponseExceptionTranslator());
}
这个configure()方法主要是对token的管理存储,认证管理器、允许token校验的请求方式
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer
.allowFormAuthenticationForClients()
.tokenKeyAccess("permitAll()")
.checkTokenAccess("permitAll()");
}
这个configure()方法是对安全点的约束,允许客户端进行表单认证,运行生成token,允许验证token接口的访问
-
继承WebSecurityConfigurerAdapter类来定义认证相关的配置类
重写 configure(AuthenticationManagerBuilder auth)方法:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(jdbcUserDetailsService).passwordEncoder(passwordEncoder);
}
其中jdbcUserDetailsService是实现UserDetailsService接口的类的实例,并重写loadUserByUsername()方法来验证用户名密码
注册认证管理器:
@Bean
@Override
@SneakyThrows
public AuthenticationManager authenticationManagerBean() {
return super.authenticationManagerBean();
}
获取token的url:
get请求:
校验token,get请求:
http://localhost:8020/oauth/check_token?token=1232435323131
刷新token,get请求:
这时候就不需要用户名密码了
总结
这篇文章主要讲了认证服务器工作的搭建和资源服务器的改造,oauth2的工作流程我们一定要掌握,这对我们工作中的认证授权的分析非常有帮助,一定要熟练掌握。
- 点赞
- 收藏
- 关注作者
评论(0)