新建一个类,用来配置认证服务器,例:AuthorizationServerConfig.java
,认证服务器配置方法:编写 @Configuration
类继承 AuthorizationServerConfigurerAdapter
,并添加 @EnableAuthorizationServer
注解,表明该类是认证服务器。
在实现认证服务器之前,我们先简单看一下 AuthorizationServerConfigurerAdapter
接口的方法,一共配置三个属性:
public class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer {
public AuthorizationServerConfigurerAdapter() {
}
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
}
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
}
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
}
}
AuthorizationServerSecurityConfigurer
:声明安全约束,哪些允许访问,哪些不允许访问。配置 AuthorizationServer 的安全属性,也就是 endpoint/oauth/token
。/oauth/authorize
则和其它用户 REST 一样保护,可以不配置。ClientDetailsServiceConfigurer
:用来配置客户端详情服务ClientDetailsService
独立client
的信息,客户端详情信息在这里进行初始化,你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息。包括权限范围、授权方式、客户端权限等配置。授权方式有4种:implicit
、client_redentials
、password
、authorization_code
, 其中密码授权方式必须结合AuthenticationManager
进行配置,必须至少配置一个客户端。AuthorizationServerEndpointsConfigurer
:用来配置AuthorizationServer
端点的非安全属性,也就是 token 存储方式、token 配置、用户授权模式等。默认不需做任何配置,除非使用 密码授权方式, 这时候必须配置 AuthenticationManager。
配置客户端详情信息
重写(@Override) void configure(ClientDetailsServiceConfigurer clients)
方法,在这里使用 JDBC 来实现客户端详情服务,如下:
/**
* 配置客户端详情信息
*
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
LogUtil.info(LOGGER, "[configure] ClientDetailsServiceConfigurer is complete. ");
clients.withClientDetails(new JdbcClientDetailsService(dataSource));
}
配置令牌
重写(@Override) void configure(AuthorizationServerEndpointsConfigurer endpoints)
方法。
/**
* 配置授权、令牌的访问端点和令牌服务
* <p>
* tokenStore:采用redis储存 authenticationManager:身份认证管理器
*
* @param endpoints endpoints
* @throws Exception Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
// 认证管理器
.authenticationManager(authenticationManager)
// 用户信息 service
.userDetailsService(userDetailsService)
// 令牌存储
.tokenStore(redisTokenStore());
endpoints.tokenServices(tokenServices());
}
配置认证规则
/**
* 配置认证规则,授权端点开放
*
* @param oauthServer oauthServer
* @throws Exception Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients()
.passwordEncoder(new BCryptPasswordEncoder())
// 开启 /oauth/token_key 验证端口无权限访问
.tokenKeyAccess("permitAll()")
// 开启 /oauth/check_token 验证端口认证权限访问
.checkTokenAccess("isAuthenticated()");
}
配置生成 token 的有效期以及存储方式
/**
* 配置生成 token 的有效期以及存储方式(此处用的redis)
* <p>
* 自定义 TokenServices 的时候,需要设置 @Primary,否则报错
*
* @return DefaultTokenServices
*/
@Primary
@Bean
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(redisTokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setClientDetailsService(clientDetails());
defaultTokenServices.setAccessTokenValiditySeconds((int) TimeUnit.MINUTES.toSeconds(30));
defaultTokenServices.setRefreshTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(1));
return defaultTokenServices;
}