Spring Security OAuth2 (一)基础SpringBoot整合OAuth
今天简单记录一下SpringBoot整合OAuth2的代码步骤
SpringBoot的1.5.21版本同SpringBoot 2.x版本有区别
本文记录的是密码式的授权方式
1、导入依赖
<!-- 以下是安全相关 -->
<!-- spring security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- spring security oauth2 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.17.RELEASE</version>
</dependency>
<!-- spring security jwt -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.0.9.RELEASE</version>
</dependency>
2、OAuth2.0使用JWT
jwt 配置类
@Configuration
public class JwtTokenConfig {
@Component("customJwtTokenEnhancer")
public class CustomJwtTokenEnhancer implements TokenEnhancer {
//实现TokenEhancer(令牌增强器)中的 ehance方法,增加额外的信息
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
//token增强逻辑,务必确保保存的信息基本不变
Map<String, Object> additionalInfo = new HashMap<>();
//可以获取到代表当前用户的信息
Object userAuthentication = authentication.getPrincipal();
additionalInfo.put("customInfo", "some_stuff_here");
// Object userAuthentication = authentication.getPrincipal();
// if (userAuthentication instanceof User) {
// User user = (User) userAuthentication;
// additionalInfo.put("id", user.getId());
// additionalInfo.put("unitId", user.getUnitId());
// additionalInfo.put("proviceSeqNo", user.getProvinceSeqNo());
// additionalInfo.put("role", user.getRole());
// }
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
}
}
配置token模式
@Bean
public TokenStore tokenStore(){
return new JwtTokenStore(jwtAccessTokenConverter());
}
jwt配置
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter(){
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey("ting");
return jwtAccessTokenConverter;
}
}
3、授权服务器
自定义授权服务器 继承 AuthorizationServerConfigurerAdapter
@Configuration
@EnableAuthorizationServer// 这个注解告诉 Spring 这个应用是 OAuth2 的授权服务器//
// 提供/oauth/authorize,/oauth/token,/oauth/check_token,/oauth/confirm_access,/oauth/error
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private JwtTokenConfig.CustomJwtTokenEnhancer customJwtTokenEnhancer;
//jwt配置
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Autowired
private TokenStore tokenStore;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients() //表单认证(申请令牌)
;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//使用内存存储client凭证,可根据情况改用jdbc存储
clients.inMemory()
.withClient("ti")
// .secret(passwordEncoder.encode("g304")) //SpringBoot2.X版本需要加密
.secret("ti")
.authorizedGrantTypes("password")
.scopes("all")
.accessTokenValiditySeconds(7200);
}
//jwtTokenStore存储
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
//将增强的token设置到增强链中
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(customJwtTokenEnhancer, jwtAccessTokenConverter));
endpoints.tokenStore(tokenStore)
.accessTokenConverter(jwtAccessTokenConverter)
.tokenEnhancer(enhancerChain);
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
// 设置添加用户信息,正常应该从数据库中读取
@Bean
UserDetailsService userDetailsService() {
InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();
userDetailsService.
createUser(User.withUsername("user_1").
password(passwordEncoder().encode("123456"))
.authorities("ROLE_USER").build());
userDetailsService.createUser(User.withUsername("user_2").password(passwordEncoder().encode("123456"))
.authorities("ROLE_USER").build());
return userDetailsService;
}
}
访问链接/oauth/token 就可以访问成功
以上是使用SpringBoot1.5.21,如果使用SpringBoot2.x版本需要进行的修改:
1、AuthenticationManager注入失败
解决办法:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
2、运行时报错和警告,是因为clients的密码格式不匹配
解决办法:
编写代码时报错的异常:
1、访问/oauth/token时候报401 authentication is required
在/oauth/token 的请求中我们指定了client_id和client_secret,所以会走ClientCredentialsTokenEndpointFilter,此时需要我们配置支持allowFormAuthenticationForClients。
在认证服务配置类中进行配置:
参考:
https://blog.csdn.net/wx2007xing/article/details/87856630
https://blog.csdn.net/weixin_44062339/article/details/102494070
https://blog.csdn.net/weixin_37769855/article/details/102840606
上一篇: 一心想联合大月氏的汉武帝,后来结果如何?
下一篇: 爆笑图片:非正常人类研究中心图片示例
推荐阅读
-
Spring Cloud实战 | 最终篇:Spring Cloud Gateway+Spring Security OAuth2集成统一认证授权平台下实现注销使JWT失效方案
-
【Spring Security】SpringCloudGateway 整合Spring Security Oauth2
-
spring security 整合 oauth2
-
Spring Security OAuth2整合JWT
-
Spring Security OAuth2 (一)基础SpringBoot整合OAuth
-
SpringBoot + Spring Security OAuth2基本使用
-
Spring Cloud实战 | 第九篇:Spring Cloud整合Spring Security OAuth2认证服务器统一认证自定义异常处理
-
【Spring Cloud Spring Security Oauth2】Spring Security Oauth2 + Redis + Gateway网关 + Mybatis + Mysql 整合
-
Spring Cloud 入门 ---- Security 整合 Oauth2 认证授权【随笔】