SpringSecurity(17)——OAuth2令牌管理策略

刷新令牌策略

注意:刷新令牌只有在授权码模式密码模式中才有,对应的指定这两种模式时,在类型上加上refresh_token

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId><version>2.3.12.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>2.3.4.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.12.RELEASE</version>
</dependency>
@Configuration
public class MyOAuth2Config {/*** 加密方式*/@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
}
/*** 当前需要使用内存方式存储了用户令牌,应当使用UserDetailsService才行,否则会报错*/
@Component
public class MyUserDetailService implements UserDetailsService {@Autowiredprivate PasswordEncoder passwordEncoder;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {return new User("admin", passwordEncoder.encode("123456"),AuthorityUtils.commaSeparatedStringToAuthorityList("admin_role"));}
}
@EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate MyUserDetailService myUserDetailService;/*** password密码模式要使用此认证管理器*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}/*** 用户类信息*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(myUserDetailService);}
}
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate MyUserDetailService myUserDetailService;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("test-pc").secret(passwordEncoder.encode("123456")).resourceIds("oauth2-server").authorizedGrantTypes("password", "authorization_code", "refresh_token").scopes("all").autoApprove(false).redirectUris("http://www.baidu.com/");}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {//密码模式需要配置认证管理器endpoints.authenticationManager(authenticationManager);//刷新令牌获取新令牌时需要endpoints.userDetailsService(myUserDetailService);}
}


令牌管理策略

  1. ResourceServerTokenServices接口定义了令牌加载、读取方法
  2. AuthorizationServerTokenServices接口定义了令牌的创建、获取、刷新方法
  3. ConsumerTokenServices定义了令牌的撤销方法(删除)
  4. DefaultTokenServices实现了上述三个接口,它包含了一些令牌业务的实现,如创建令牌、读取令牌、刷新令牌、获取客户端ID。默认的创建一个令牌时,是使用 UUID 随机值进行填充的。除了持久化令牌是委托一个 TokenStore 接口实现以外,这个类几乎帮你做了所有事情

TokenStore接口负责持久化令牌,默认情况下,令牌是通过randomUUID产生的32位随机数来进行填充,从而产生的令牌默认是存储在内存中

  • 内存存储采用的是TokenStore接口默认实现类InMemoryTokenStore,开发时方便调试,适用单机版
  • RedisTokenStore将令牌存储到Redis非关系型数据库,适用于高并发服务
  • JdbcTokenStore基于JDBC将令牌存储到关系型数据库中,可以在不同的服务器间共享令牌
  • JWtTokenStore将用户信息存储到令牌中,这样后端就可以不存储,前端拿到令牌后可以直接解析出用户信息。

内存管理令牌

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId><version>2.3.12.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>2.3.4.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.12.RELEASE</version>
</dependency>
@Configuration
public class MyOAuth2Config {@Beanpublic TokenStore tokenStore(){return new InMemoryTokenStore(); }@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
}
/*** 当前需要使用内存方式存储了用户令牌,应当使用UserDetailsService才行,否则会报错*/
@Component
public class MyUserDetailService implements UserDetailsService {@Autowiredprivate PasswordEncoder passwordEncoder;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {return new User("admin", passwordEncoder.encode("123456"),AuthorityUtils.commaSeparatedStringToAuthorityList("admin_role"));}
}
@EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate MyUserDetailService myUserDetailService;/*** password密码模式要使用此认证管理器*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}/*** 用户类信息*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(myUserDetailService);}
}
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate MyUserDetailsService myUserDetailsService;@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate TokenStore tokenStore;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("test-pc").secret(passwordEncoder.encode("123456")).resourceIds("oauth2-server").authorizedGrantTypes("authorization_code", "password", "implicit", "client_credentials", "refresh_token").scopes("all").autoApprove(false).redirectUris("http://www.baidu.com");}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager);endpoints.userDetailsService(myUserDetailsService);//令牌管理策略endpoints.tokenServices(tokenService());}@Bean public AuthorizationServerTokenServices tokenService() { DefaultTokenServices service=new DefaultTokenServices();//service.setClientDetailsService();//客户端详情服务service.setSupportRefreshToken(true);//支持刷新令牌service.setTokenStore(tokenStore);//令牌存储策略service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天return service;}
}

Redis管理令牌

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId><version>2.3.12.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>2.3.4.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.12.RELEASE</version>
</dependency>
@Configuration
public class MyOAuth2Config {@Autowiredprivate RedisConnectionFactory redisConnectionFactory;@Beanpublic TokenStore redisTokenStore(){// redis管理令牌return new RedisTokenStore(redisConnectionFactory);}@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
}
/*** 当前需要使用内存方式存储了用户令牌,应当使用UserDetailsService才行,否则会报错*/
@Component
public class MyUserDetailService implements UserDetailsService {@Autowiredprivate PasswordEncoder passwordEncoder;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {return new User("admin", passwordEncoder.encode("123456"),AuthorityUtils.commaSeparatedStringToAuthorityList("admin_role"));}
}
@EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate MyUserDetailService myUserDetailService;/*** password密码模式要使用此认证管理器*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}/*** 用户类信息*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(myUserDetailService);}
}
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate MyUserDetailsService myUserDetailsService;@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate TokenStore tokenStore;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("test-pc").secret(passwordEncoder.encode("123456")).resourceIds("oauth2-server").authorizedGrantTypes("authorization_code", "password", "implicit", "client_credentials", "refresh_token").scopes("all").autoApprove(false).redirectUris("http://www.baidu.com");}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager);endpoints.userDetailsService(myUserDetailsService);//令牌管理策略endpoints.tokenStore(tokenStore);}
}

JDBC管理令牌

建表语句

具体SQL语句可以去官网查看

-- used in tests that use HSQL
create table oauth_client_details (client_id VARCHAR(128) PRIMARY KEY,resource_ids VARCHAR(256),client_secret VARCHAR(256),scope VARCHAR(256),authorized_grant_types VARCHAR(256),web_server_redirect_uri VARCHAR(256),authorities VARCHAR(256),access_token_validity INTEGER,refresh_token_validity INTEGER,additional_information VARCHAR(4096),autoapprove VARCHAR(256)
);
INSERT INTO `oauth_client_details` VALUES ('test-pc', 'oauth2-server,oauth2-resource', '$2a$10$Q2Dv45wFHgxQkFRaVNAzeOJorpTH2DwHb975VeHET30QsqwuoQOAe', 'all,Base_API', 'authorization_code,password,implicit,client_credentials,refresh_token', 'http://www.baidu.com/', NULL, 50000, NULL, NULL, 'false');create table oauth_client_token (token_id VARCHAR(256),token BLOB,authentication_id VARCHAR(256) PRIMARY KEY,user_name VARCHAR(256),client_id VARCHAR(256)
);create table oauth_access_token (token_id VARCHAR(256),token BLOB,authentication_id VARCHAR(256) PRIMARY KEY,user_name VARCHAR(256),client_id VARCHAR(256),authentication BLOB,refresh_token VARCHAR(256)
);create table oauth_refresh_token (token_id VARCHAR(256),token BLOB,authentication BLOB
);create table oauth_code (code VARCHAR(256), authentication BLOB
);create table oauth_approvals (userId VARCHAR(256),clientId VARCHAR(256),scope VARCHAR(256),status VARCHAR(10),expiresAt TIMESTAMP,lastModifiedAt TIMESTAMP
);-- customized oauth_client_details table
create table ClientDetails (appId VARCHAR(256) PRIMARY KEY,resourceIds VARCHAR(256),appSecret VARCHAR(256),scope VARCHAR(256),grantTypes VARCHAR(256),redirectUrl VARCHAR(256),authorities VARCHAR(256),access_token_validity INTEGER,refresh_token_validity INTEGER,additionalInformation VARCHAR(4096),autoApproveScopes VARCHAR(256)
);

基本使用

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>2.3.4.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3.4</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version>
</dependency>
server:port: 8080
spring:application:name: oauth2-serverdatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/oauth2?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8username: rootpassword: 123456type: com.alibaba.druid.pool.DruidDataSource
@Configuration
public class MyOauth2Config {/*** druid数据源*/@Bean@ConfigurationProperties(prefix = "spring.datasource")public DataSource druidDataSource() {return new DruidDataSource();}/*** jdbc管理令牌*/@Beanpublic TokenStore jdbcTokenStore() {return new JdbcTokenStore(druidDataSource());}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthenticationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate MyUserDetailsService myUserDetailsService;@Autowiredprivate TokenStore tokenStore;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("test-pc").secret(passwordEncoder.encode("123456")).resourceIds("oauth2-server").authorizedGrantTypes("authorization_code", "password", "implicit", "client_credentials", "refresh_token").scopes("all").autoApprove(false).redirectUris("http://www.baidu.com");}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager);endpoints.userDetailsService(myUserDetailsService);//令牌管理策略endpoints.tokenStore(tokenStore);}
}

JWT管理令牌

基本使用

<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-jwt</artifactId><version>1.1.1.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId><version>2.3.12.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>2.3.4.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.12.RELEASE</version>
</dependency>
@Configuration
public class MyOAuth2Config {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Beanpublic TokenStore tokenStore() {// JWT令牌存储方式return new JwtTokenStore(jwtAccessTokenConverter());}/*** 帮助JWT编码的令牌值在OAuth身份验证信息之间进行转换* JwtAccessTokenConverter是TokenEnhancer的一个实例*/@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();// JWT签名的秘钥,这里使用的是对称加密,资源服务器使用该秘钥来验证converter.setSigningKey("jwt");return converter;}
}
/*** 当前需要使用内存方式存储了用户令牌,应当使用UserDetailsService才行,否则会报错*/
@Component
public class MyUserDetailService implements UserDetailsService {@Autowiredprivate PasswordEncoder passwordEncoder;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {return new User("admin", passwordEncoder.encode("123456"),AuthorityUtils.commaSeparatedStringToAuthorityList("admin_role"));}
}
@EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate MyUserDetailService myUserDetailService;/*** password密码模式要使用此认证管理器*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}/*** 用户类信息*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(myUserDetailService);}
}
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate MyUserDetailService myUserDetailService;@Autowiredprivate TokenStore tokenStore;@Autowiredprivate JwtAccessTokenConverter jwtAccessTokenConverter;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("test-pc").secret(passwordEncoder.encode("123456")).resourceIds("oauth2-server").authorizedGrantTypes("password", "authorization_code", "refresh_token").scopes("all").autoApprove(false).redirectUris("http://www.baidu.com/");}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {//密码模式需要配置认证管理器endpoints.authenticationManager(authenticationManager);//刷新令牌获取新令牌时需要endpoints.userDetailsService(myUserDetailService);endpoints.tokenStore(tokenStore);//配置JwtAccessToken转换器,将值转换为jwtendpoints.accessTokenConverter(jwtAccessTokenConverter);}@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {//security.allowFormAuthenticationForClients();//所有人都可访问/oauth/token_key,后面要获取公钥,默认拒绝访问//注意:rsa时才有用,其他需要先认证才访问该接口security.tokenKeyAccess("permitAll()");//认证后可访问/oauth/check_token,默认拒绝访问security.checkTokenAccess("permitAll()");}
}

获取JWT令牌,并将其解析
image.png
image.png

实现TokenEnhancer自定义token内容增强器

Token解析将得到PAYLOAD,如果想在JWT中添加额外信息,需要实现TokenEnhancer,相当于是一个Token增强器

@Configuration
public class MyOAuth2Config {@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Beanpublic TokenStore tokenStore() {// JWT令牌存储方式return new JwtTokenStore(jwtAccessTokenConverter());}/*** 帮助JWT编码的令牌值在OAuth身份验证信息之间进行转换* JwtAccessTokenConverter是TokenEnhancer的一个实例*/@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();// JWT签名的秘钥,这里使用的是对称加密,资源服务器使用该秘钥来验证converter.setSigningKey("jwt");return converter;}
}
/*** token内容增强器*/
@Component
public class JwtTokenEnhancer implements TokenEnhancer {@Overridepublic OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {Map<String, Object> info = new HashMap<>();//为原有的token的载荷增加一些内容//在对token进行解密时就可以拿到这里添加的信息info.put("enhance", "enhance info");((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(info);return oAuth2AccessToken;}
}
@EnableWebSecurity
public class OAuth2SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate MyUserDetailService myUserDetailService;/*** password密码模式要使用此认证管理器*/@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}/*** 用户类信息*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(myUserDetailService);}
}
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate MyUserDetailService myUserDetailService;@Autowiredprivate TokenStore tokenStore;@Autowiredprivate JwtAccessTokenConverter jwtAccessTokenConverter;@Autowiredprivate JwtTokenEnhancer jwtTokenEnhancer;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("test-pc").secret(passwordEncoder.encode("123456")).resourceIds("oauth2-server").authorizedGrantTypes("password", "authorization_code", "refresh_token").scopes("all").autoApprove(false).redirectUris("http://www.baidu.com/");}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {//配置JWT的内容增强器,TokenEnhancer可以对token进行增强TokenEnhancerChain enhancerChain = new TokenEnhancerChain();List<TokenEnhancer> delegates = new ArrayList<>();//添加token增强器delegates.add(jwtTokenEnhancer);//添加转换器delegates.add(jwtAccessTokenConverter);//把增强内容放入增强链中enhancerChain.setTokenEnhancers(delegates);//密码模式需要配置认证管理器endpoints.authenticationManager(authenticationManager);//刷新令牌获取新令牌时需要endpoints.userDetailsService(myUserDetailService);endpoints.tokenStore(tokenStore);//配置JwtAccessToken转换器,将值转换为jwtendpoints.accessTokenConverter(jwtAccessTokenConverter);//配置token增强链endpoints.tokenEnhancer(enhancerChain);}@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {//所有人都可访问/oauth/token_key,后面要获取公钥,默认拒绝访问security.tokenKeyAccess("permitAll()");//认证后可访问/oauth/check_token,默认拒绝访问security.checkTokenAccess("permitAll()");}
}

image.png
image.png

利用令牌管理服务管理JWT令牌

@Configuration
public class MyOAuth2Config {@Autowiredprivate JwtTokenEnhancer jwtTokenEnhancer;@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}@Beanpublic TokenStore tokenStore(){return new JwtTokenStore(jwtAccessTokenConverter());}@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter(){JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter.setSigningKey("123");return converter;}/*** 令牌管理服务*/@Beanpublic AuthorizationServerTokenServices authorizationServerTokenServices(){DefaultTokenServices tokenServices = new DefaultTokenServices();// 客户端详情,因为是向客户端颁发令牌,所以需要知道是哪一个客户端/*tokenServices.setClientDetailsService();*/// 是否支持刷新令牌tokenServices.setSupportRefreshToken(true);// 令牌存储策略tokenServices.setTokenStore(tokenStore());// 设置令牌增强TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();List<TokenEnhancer> delegates = new ArrayList<>();delegates.add(jwtTokenEnhancer);delegates.add(jwtAccessTokenConverter());tokenEnhancerChain.setTokenEnhancers(delegates);tokenServices.setTokenEnhancer(tokenEnhancerChain);// access_token默认有效期2小时tokenServices.setAccessTokenValiditySeconds(7200);// refresh_token默认有效期3天tokenServices.setRefreshTokenValiditySeconds(259200);return tokenServices;}
}
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate MyUserDetailService myUserDetailService;@Autowiredprivate AuthorizationServerTokenServices authorizationServerTokenServices;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("test-pc").secret(passwordEncoder.encode("123456")).resourceIds("oauth2-server").authorizedGrantTypes("password", "authorization_code", "refresh_token").scopes("all").autoApprove(false).redirectUris("http://www.baidu.com/");}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {//密码模式需要配置认证管理器endpoints.authenticationManager(authenticationManager);//刷新令牌获取新令牌时需要endpoints.userDetailsService(myUserDetailService);//令牌管理服务endpoints.tokenServices(authorizationServerTokenServices);}@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {//所有人都可访问/oauth/token_key,后面要获取公钥,默认拒绝访问security.tokenKeyAccess("permitAll()");//认证后可访问/oauth/check_token,默认拒绝访问security.checkTokenAccess("permitAll()");}
}

令牌端点的安全策略

  1. /oauth/authorize:申请授权码code,涉及类AuthorizationEndpoint
  2. /oauth/token:获取令牌token,涉及类TokenEndpoint
  3. /oauth/check_token:用于资源服务器请求端点来检查令牌是否有效,涉及类CheckTokenEndpoint
  4. /oauth/confirm_access:用于确认授权提交,涉及类WhitwlabelApprovalEndpoint
  5. /oauth/error:授权错误信息,涉及类WhitelabelErrorEndpoint
  6. /oauth/token_key:提供公有密钥的端点,使用JWT令牌时会使用,涉及类TokenKeyEndpoint

默认情况下/oauth/check_token和/oauth/token_key端点默认是denyAll()拒绝访问的权限,如果这两个端点需要访问,要对他们进行认证和授权才可以访问
image.png

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthenticationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate MyUserDetailsService myUserDetailsService;@Autowiredprivate TokenStore tokenStore;@Autowiredprivate AuthorizationCodeServices jdbcAuthorizationCodeServices;@Autowiredprivate ClientDetailsService jdbcClientDetailsService;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.withClientDetails(jdbcClientDetailsService);}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager);endpoints.userDetailsService(myUserDetailsService);//令牌管理策略endpoints.tokenStore(tokenStore);//授权码管理策略,针对授权码模式有效,会将授权码放到oauth_code表,授权后就删除它endpoints.authorizationCodeServices(jdbcAuthorizationCodeServices);}@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {//所有人都可访问/oauth/token_key,后面要获取rsa公钥,默认拒绝访问//注意:rsa时才有用,其他需要先认证才访问该接口security.tokenKeyAccess("permitAll()");//认证后可访问/oauth/check_token,默认拒绝访问security.checkTokenAccess("isAuthenticated()");}
}

image.png
image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/670669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Flink入门修炼】1-1 为什么要学习 Flink?

流处理和批处理是什么&#xff1f; 什么是 Flink&#xff1f; 为什么要学习 Flink&#xff1f; Flink 有什么特点&#xff0c;能做什么&#xff1f; 本文将为你解答以上问题。 一、批处理和流处理 早些年&#xff0c;大数据处理还主要为批处理&#xff0c;一般按天或小时定时处…

如何在docker中访问电脑上的GPU?如何在docker中使用GPU进行模型训练或者加载调用?

如何在docker中访问电脑上的GPU&#xff1f;如何在docker中使用GPU进行模型训练或者加载调用&#xff1f; 其实使用非常简单&#xff0c;只是一行命令的事&#xff0c;最主要的事配置好驱动和权限。 docker run -it --rm --gpus all ycj520/centos:1.0.0 nvidia-smi先看看 st…

Kafka 使用手册

kafka3.0 文章目录 kafka3.01. 什么是kafka&#xff1f;2. kafka基础架构3. kafka集群搭建4. kafka命令行操作主题命令行【topic】生产者命令行【producer】消费者命令行【consumer】 5. kafka生产者生产者消息发送流程Producer 发送原理普通的异步发送带回调函数的异步发送同步…

golang压缩与解压缩文件

全代码实现&#xff0c;如有帮助&#xff0c;欢迎留下足迹。 目录 压缩 核心处理 解压缩 压缩 入口压缩函数 useBasePathInZip参数&#xff1a; 为 false 相当于全文件视图&#xff0c;zip中没有目录 为 true表示保留源文件的路径&#xff08;srcPaths如果是相对路径&#…

【量子通信】量子通信技术:前景与挑战

量子通信技术&#xff1a;前景与挑战 一、技术背景二、技术原理量子叠加性&#xff1a;量子纠缠性&#xff1a;量子测量&#xff1a;量子不可克隆定理&#xff1a; 三、技术优缺点优点&#xff1a;安全性高&#xff1a;传输速度快&#xff1a;抗干扰性强&#xff1a;传输能力强…

CentOS 中文乱码

CentOS 中文乱码 1、 查看自己系统有没有安装中文语言包&#xff0c;可使用 locale -a 命令列出所有可用的语言环境 如果有中文&#xff0c;则不用安装&#xff0c;如果没有&#xff0c;需要重新安装&#xff0c;使用 yum install kde-l10n-Chinese 2、 修改 i18n 和 locale…

C++奇淫巧计:如何自助控制对象的初始化和销毁

需求 我们需要一个对象时&#xff0c;new 出来后自动根据需求&#xff0c;或是默认构造函数或是拷贝构造函数或是隐式转换&#xff0c;拿到手后就能用&#xff0c;习以为常。 但我们其实可以精确控制 new 的两个行为——内存分配、内存初始化。 代码 #include <iostream…

Mac OS中创建适合网络备份的加密镜像文件:详细步骤与参数选择

这篇文章提供了在Mac OS中创建适合网络备份的加密镜像文件的详细步骤&#xff0c;同时探讨了在选择相关参数时的关键考虑因素&#xff0c;以确保用户能够安全、高效地存储和保护重要数据。 创建步骤 在Mac OS Monterey中&#xff0c;你可以使用“磁盘工具”&#xff08;Disk …

【C++】初始化列表--再谈构造函数

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

PXI-1 Peripheral Module 64Bit 改混合槽 PXI Express Hybrid Slot

PXI PXIEPXI_LBR05VauxPXI_LBR2WAKE#PXI_LBR3ALERT#PXI_LBR412VPXI_LBR512VPXI_LBRL0/PXI_STAR0GNDPXI_LBRL1/PXI_STAR1GNDPXI_LBRL2/PXI_STAR2GNDPXI_LBRL3/PXI_STAR33.3VPXI_LBRL4/PXI_STAR43.3VPXI_LBRL5/PXI_STAR53.3V 实际就是拆掉这个 红黄框里的端子。。

UE4 C++ 动态加载类和资源

动态加载类和资源&#xff1a;指在运行时加载 .cpp void AMyActor::BeginPlay() {Super::BeginPlay();//动态加载资源UStaticMesh* MyTempStaticMesh LoadObject<UStaticMesh>(nullptr,TEXT("/Script/Engine.StaticMesh/Game/StarterContent/Shapes/Shape_NarrowC…

RTthread线程间通信(邮箱,消息队列,信号/软件中断)---03信号(软件中断)源码分析

信号 实际使用看这一个 #if defined(RT_USING_SIGNALS)rt_sigset_t sig_pending; /**< the pending signals 记录来了的信号 */rt_sigset_t sig_mask; /**< the mask bits of signal 记录屏蔽的信号 */rt_sigh…

Android9~Android13 某些容量SD卡被格式化为内部存储时容量显示错误问题的研究与解决方案

声明:原创文章,禁止转载! Android9~Android13 某些容量SD卡被格式化为内部存储时容量显示错误问题的研究与解决方案 分析Android11 系统对于EMMC/UFS作为内部存储、SD卡被格式化为内部存储、SD卡/U盘被格式化为便携式存储的不同处理 一.现象描述 实测Android9 Android10 A…

Aigtek高精度电压源什么作用

高精度电压源是一种能够提供稳定、可靠且精确的电压输出的电子设备。它在科学研究、工程应用和制造业中起着至关重要的作用。以下将详细介绍高精度电压源的作用及其在不同领域的应用。 一、工作原理 稳定性&#xff1a;高精度电压源通常采用精密的电路设计和稳压技术&#xff0…

Java开发IntelliJ IDEA2023

IntelliJ IDEA 2023是一款强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为Java开发人员设计。它提供了许多特色功能&#xff0c;帮助开发人员更高效地编写、测试和调试Java应用程序。以下是一些IntelliJ IDEA 2023的特色功能&#xff1a; 智能代码编辑器&…

软件系统架构的演变历史介绍

个人浅见&#xff0c;不喜勿喷&#xff0c;非常感谢。 软件系统架构的演变历史与计算机技术的发展紧密相连。从最早的单一大型计算机&#xff0c;到个人计算机的兴起&#xff0c;再到互联网和云计算的普及&#xff0c;软件系统架构经历了多次重大的变革。以下是软件系统…

探索回溯算法

前言 回溯算法称之通用解算法&#xff0c;任何问题都可以优先使用回溯算法思考&#xff0c;再进行优化改进。那要问上一句回溯算法是怎样思维方式&#xff1f; 一&#xff0c;回溯算法思想 回溯算法是一个类似枚举的搜索尝试过程&#xff0c;主要是在搜索尝试过程中寻找问题…

Jgit Packfile is truncated解决方案

配置方式解决 这两个配置选项是用于提高 SSH 连接稳定性的 SSH 客户端配置参数&#xff0c;它们被添加到 SSH 配置文件&#xff08;通常是 ~/.ssh/config&#xff09;中。这些参数有助于在网络不稳定或者长时间无数据交换时保持 SSH 连接不被断开。下面是每个参数的具体作用&am…

【并行编程框架】AsyncTool

文章目录 AsyncToolAsyncTool是什么&#xff1f;AsyncTool快速入门1&#xff09;导入依赖2&#xff09;自定义Worker3&#xff09;编排包装类Wrapper4&#xff09;提交任务执行5&#xff09;运行结果 并发编程常见的场景串行并行阻塞等待 - 先串行&#xff0c;后并行阻塞等待 -…

电力负荷预测 | 基于TCN的电力负荷预测(Python)———数据预处理

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 基于TCN的电力负荷预测(Python) python3.8 keras2.6.0 matplotlib3.5.2 numpy1.19.4 pandas1.4.3 tensorflow==2.6.0