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 发送原理普通的异步发送带回调函数的异步发送同步…

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…

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; 智能代码编辑器&…

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

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

浏览器提示ERR_SSL_KEY_USAGE_INCOMPATIBLE解决

ERR_SSL_KEY_USAGE_INCOMPATIBLE报错原因 ERR_SSL_KEY_USAGE_INCOMPATIBLE 错误通常发生在使用 SSL/TLS 连接时,指的是客户端和服务器之间进行安全通信尝试失败,原因是证书中的密钥用途(Key Usage)或扩展密钥用途(Extended Key Usage, EKU)与正在尝试的操作不兼容。这意味…

Unity笔记:相机移动

基础知识 鼠标输入 在Unity中&#xff0c;开发者在“Edit” > “Project Settings” > “Input Manager”中设置输入&#xff0c;如下图所示&#xff1a; 在设置了Mouse X后&#xff0c;Input.GetAxis("Mouse X")返回的是鼠标在X轴上的增量值。这意味着它会…

STM32TIM定时器(3)

文章目录 前言一、介绍部分输入捕获简介频率测量捕获比较通道主从模式输入捕获基本结构PWMI基本结构 二、代码部分使用输入捕获捕获另一个端口的PWM输入线路连接代码内容 PWMI获取频率占空比线路连接与上个案例一致代码实现 总结相关函数PSC、ARR都有1的误差 前言 这部分主要介…

Spring Boot整合新版Spring Security:Lambda表达式配置优雅安全

文章目录 1. 引言2. 项目依赖配置3. 使用Lambda表达式配置Spring Security4. 自定义身份验证逻辑5. 认证与授权注解5.1 Secured注解5.2 PreAuthorize和PostAuthorize注解 6. 总结 &#x1f389;Spring Boot整合新版Spring Security&#xff1a;Lambda表达式配置优雅安全 ☆* o(…

spring cloud stream

背景 主要解决不同消息中间件切换问题。实现不同中间件的代码解耦。 链接: 支持的中间件 后文使用kafka测试。 引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream</artifactId></depende…

Spring Web Body 转化常见错误

在 Spring 中&#xff0c;对于 Body 的处理很多是借助第三方编解码器来完成的。例如常见的 JSON 解析&#xff0c;Spring 都是借助于 Jackson、Gson 等常见工具来完成。所以在 Body 处理中&#xff0c;我们遇到的很多错误都是第三方工具使用中的一些问题。 真正对于 Spring 而…

2024年 复习 HTML5+CSS3+移动web 笔记 之CSS遍 第5天

第 五 天 整个网站例 5.1 准备工作 项目目录与版心 base.css 5.2 网页制作思路 5.3 header 区域-整体布局 5.4 header区域-logo 5.5 header区域-导航 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&l…

网桥与网关

文章目录 概要网桥网关联系与区别参考文章 概要 网桥和网关的理解 网桥 几个名词的概念 网关 联系与区别 参考文章 如何通俗地解释什么是网桥&#xff1f; 网关到底是什么求通俗易懂讲解? 网桥&#xff1a;网桥也叫桥接器&#xff0c;是连接两个局域网的一种存储/转发…

C语言第十九弹---指针(三)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 指针 1、数组名的理解 2、使用指针访问数组 3、⼀维数组传参的本质 4、冒泡排序 5、二级指针 6、指针数组 7、指针数组模拟二维数组 总结 1、数组名的理解…