正文
关于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等等。
下面讲解认证与授权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中的信息,下面会讲到。