这篇讲的内容是:Oauth2在SpringBoot/SpringCloud中的实战。
SpringBoot版本:2.2.5.Release
SpringCloud版本:Hoxton.SR9
JDK版本:1.8
1:POM配置
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 -->
<dependency>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<groupId>org.springframework.cloud</groupId>
</dependency>
<!--使用redis存放token-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--密码加密解密依赖包-->
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.2</version>
</dependency>
</dependencies>
2:关键配置
2.1:认证服务配置-WebAuthorizationConfig
@Configuration
@EnableAuthorizationServer
public class WebAuthorizationConfig extends AuthorizationServerConfigurerAdapter {
private final AuthenticationManager authenticationManager;
private final UserDetailsService userDetailsService;
private final PasswordEncoder passwordEncoder;
private final TokenStore tokenStore;
private final AuthorizationCodeServices authorizationCodeServices;
private final AuthTokenExceptionHandler authTokenExceptionHandler;
public WebAuthorizationConfig(AuthenticationManager authenticationManager,
UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder,
TokenStore tokenStore,
AuthorizationCodeServices authorizationCodeServices,
AuthTokenExceptionHandler authTokenExceptionHandler) {
this.authenticationManager = authenticationManager;
this.userDetailsService = userDetailsService;
this.passwordEncoder = passwordEncoder;
this.tokenStore = tokenStore;
this.authorizationCodeServices = authorizationCodeServices;
this.authTokenExceptionHandler = authTokenExceptionHandler;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
String secret = PasswordHelper.encryptPassword(Oauth2ClientUserEnums.ADMIN.getClientSecret());
clients.inMemory()
.withClient(Oauth2ClientUserEnums.ADMIN.getClientId())
.secret(secret)
.scopes("all", "test")
.resourceIds("admin")
// autoApprove 可跳过授权页直接返回code
.autoApprove("all")
.redirectUris("http://www.baidu.com")
//客户端认证所支持的授权类型 1:客户端凭证 2:账号密码 3:授权码 4:token刷新 5:简易模式
.authorizedGrantTypes(CLIENT_CREDENTIALS, PASSWORD, REFRESH_TOKEN, AUTHORIZATION_CODE, IMPLICIT)
//用户角色
.authorities("admin")
//允许自动授权
.autoApprove(false)
//token 过期时间
.accessTokenValiditySeconds((int) TimeUnit.HOURS.toSeconds(12))
//refresh_token 过期时间
.refreshTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(30))
;
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.passwordEncoder(passwordEncoder)
//设置密码编辑器
.allowFormAuthenticationForClients()
.tokenKeyAccess("permitAll()")
//开启 /oauth/token_key 的访问权限控制
.checkTokenAccess("permitAll()")
//开启 /oauth/check_token 验证端口认证权限访问
;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 配置授权服务器端点的属性
endpoints.authenticationManager(authenticationManager) //认证管理器
.tokenStore(tokenStore)
.authorizationCodeServices(authorizationCodeServices)
.userDetailsService(userDetailsService)
.exceptionTranslator(authTokenExceptionHandler);
}
}
注解:@EnableAuthorizationServer表明当前服务是认证服务。
介绍一下几个基础组件
①:authenticationManager
认证管理器,对客户端凭证、用户进行认证的地方。
②:tokenStore
存放token的地方,默认是存放在Inmemory(内存)中的。
③:authorizationCodeServices
code生成服务,使用默认的即可。
④:userDetailsService
用户详情服务,可重写实现,用户信息从数据库中加载。
⑤:authTokenExceptionHandler
自定义的 token 鉴别失败异常处理器。
⑥:authClientExceptionHandler
自定义的 客户端凭证 鉴别失败异常处理器。
2.2:资源服务配置-WebResourceConfig
@Configuration
@EnableResourceServer
public class WebResourceConfig extends ResourceServerConfigurerAdapter {
private final AuthClientExceptionHandler authClientExceptionHandler;
public WebResourceConfig(AuthClientExceptionHandler authClientExceptionHandler) {
this.authClientExceptionHandler = authClientExceptionHandler;
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId("admin").stateless(true).authenticationEntryPoint(authClientExceptionHandler);
}
@Override
public void configure(HttpSecurity http) throws Exception {
// 资源链路
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and().formLogin().permitAll()
// 登录放通
.and()
.authorizeRequests()
.antMatchers("/oauth/**", "/favicon.ico")
//.authenticated()
.permitAll()
// 其他请求都需认证
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
// 跨域
.and()
.cors()
// 关闭跨站请求防护
.and()
.csrf()
.disable();
}
}
注解:@EnableResourceServer表明当前服务是认证服务。