聊聊微服务认证之Oauth2

举报
周杰伦本人 发表于 2022/09/29 14:58:29 2022/09/29
【摘要】 聊聊微服务认证之Oauth2 把业务服务器变成资源服务器: 搭建认证服务器 总结 聊聊微服务认证之Oauth2Oauth2是基于token的认证方式,它打通了web端和app端的统一认证,认证数据不需要存储在服务端,客户端只需要携带token就可以实现认证这里说一下Oauth2的认证流程:首先客户端会向资源拥有者发起请求授权,例如微信然后资源拥有者进行确认授权,例如输入微信用户名密码后点击...

聊聊微服务认证之Oauth2

Oauth2是基于token的认证方式,它打通了web端和app端的统一认证,认证数据不需要存储在服务端,客户端只需要携带token就可以实现认证

这里说一下Oauth2的认证流程:

  1. 首先客户端会向资源拥有者发起请求授权,例如微信
  2. 然后资源拥有者进行确认授权,例如输入微信用户名密码后点击确认授权
  3. 这时客户端收到授权许可之后就会向认证服务器发起请求,申请令牌
  4. 认证服务器收到请求之后生成token给客户端
  5. 然后客户端携带token信息来访问资源服务器,这里比如获取微信昵称等等信息
  6. 资源服务器会先调用认证服务器验证token是否有效
  7. 资源服务器将资源返回给客户端,也就是把微信信息

一般情况下会有网关,客户端会先请求网关,网关调用认证服务器获取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

搭建认证服务器

  1. 继承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接口的访问

  1. 继承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请求:

http://localhost:8020/oauth/token?grant_type=password&client_id=client&client_secret=secret&username=xiepanpan&password=123456

校验token,get请求:

http://localhost:8020/oauth/check_token?token=1232435323131

刷新token,get请求:

http://localhost:8020/oauth/token?grant_type=refresh_token&refresh_token=f6c882b8-d9e1-43c3-b41d-291b335775d9&client_id=client&client_secret=secret

这时候就不需要用户名密码了

总结

这篇文章主要讲了认证服务器工作的搭建和资源服务器的改造,oauth2的工作流程我们一定要掌握,这对我们工作中的认证授权的分析非常有帮助,一定要熟练掌握。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。