专栏名称: 分布式实验室
最专业的Docker文章,最权威的Docker新闻。关注容器生态圈的发展。
目录
相关文章推荐
51好读  ›  专栏  ›  分布式实验室

认证鉴权与API权限控制在微服务架构中的设计与实现(二)

分布式实验室  · 公众号  · 后端  · 2017-10-27 07:45

正文

请到「今天看啥」查看全文


关于AuthorizationServer和ResourceServer的配置在上一篇文章已经列出。AuthorizationServer主要是继承了AuthorizationServerConfigurerAdapter,覆写了其实现接口的三个方法:


//对应于配置AuthorizationServer安全认证的相关信息,创建ClientCredentialsTokenEndpointFilter核心过滤器
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { 
}
//配置OAuth2的客户端相关信息
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
}
//配置身份认证器,配置认证方式,TokenStore,TokenGranter,OAuth2RequestFactory
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
}


2.2 主要Authentication类的类图



AuthorizationServer UML类图


主要的验证方法authenticate(Authentication authentication)在接口AuthenticationManager中,其实现类有ProviderManager,有上图可以看出ProviderManager又依赖于AuthenticationProvider接口,其定义了一个List 全局变量。笔者这边实现了该接口的实现类CustomAuthenticationProvider。自定义一个provider,并在GlobalAuthenticationConfigurerAdapter中配置好改自定义的校验provider,覆写configure()方法。


@Configuration
public class AuthenticationManagerConfig extends GlobalAuthenticationConfigurerAdapter {
@Autowired
CustomAuthenticationProvider customAuthenticationProvider;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthenticationProvider);//使用自定义的AuthenticationProvider
}
}


AuthenticationManagerBuilder是用来创建AuthenticationManager,允许自定义提供多种方式的AuthenticationProvider,比如LDAP、基于JDBC等等。


3. 认证与授权token


下面讲解认证与授权token主要的类与接口。


3.1 自定义的验证类CustomAuthenticationProvider


CustomAuthenticationProvider中定义了验证方法的具体实现。其具体实现如下所示。


//主要的自定义验证方法
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
   String username = authentication.getName();
   String password = (String) authentication.getCredentials();
   Map data = (Map) authentication.getDetails();
   String clientId = (String) data.get("client");
   Assert.hasText(clientId,"clientId must have value" );
   String type = (String) data.get("type");
   //通过调用user服务,校验用户信息
   Map map = userClient.checkUsernameAndPassword(getUserServicePostObject(username, password, type));
    //校验返回的信息,不正确则抛出异常,授权失败
   String userId = (String) map.get("userId");
   if (StringUtils.isBlank(userId)) {
       String errorCode = (String) map.get("code");
       throw new BadCredentialsException(errorCode);
   }
   CustomUserDetails customUserDetails = buildCustomUserDetails(username, password, userId, clientId);
   return new CustomAuthenticationToken(customUserDetails);
}
//构造一个CustomUserDetails,简单,略去
private CustomUserDetails buildCustomUserDetails(String username, String password, String userId, String clientId) {
}
//构造一个请求userService的map,内容略
private Map getUserServicePostObject(String username, String password, String type) {
}


authenticate()最后返回构造的自定义CustomAuthenticationToken,在CustomAuthenticationToken中,将boolean authenticated设为true,user信息验证成功。这边传入的参数CustomUserDetails与token生成有关,作为payload中的信息,下面会讲到。







请到「今天看啥」查看全文