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.hqwc.cn/news/454820.html

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

相关文章

【优先级队列(大顶堆 小顶堆)】【遍历哈希表键值对】Leetcode 347 前K个高频元素

【优先级队列&#xff08;大顶堆 小顶堆&#xff09;】【排序】Leetcode 347 前K个高频元素 1.不同排序法归纳2.大顶堆和小顶堆3.PriorityQueue操作4.PriorityQueue的升序&#xff08;默认&#xff09;与降序5.问题解决&#xff1a;找前K个最大的元素 &#xff1a;踢走最小的&…

Mixed Content: The page at ‘xxx‘ was loaded over HTTPS, but requested an insecure XMLHttpRequest end

Mixed Content: The page at xxx was loaded over HTTPS, but requested an insecure XMLHttpRequest end 报错信息报错的原因出现的问题解决办法 报错信息 Mixed Content: The page at xxx was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint xxx. Th…

挑战杯 opencv 图像识别 指纹识别 - python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于机器视觉的指纹识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&#xff0c;适…

功能测试+自动化测试代码覆盖率统计

Jacoco 是一个开源的覆盖率工具。Jacoco 可以嵌入到 Ant 、Maven 中&#xff0c;并提供了 EclEmma Eclipse 插件,也可以使用 Java Agent 技术监控 Java 程序。很多第三方的工具提供了对 Jacoco 的集成&#xff0c;如 sonar、Jenkins、IDEA。 Jacoco 包含了多种尺度的覆盖率计数…

研究表明:论文被大V宣传后,引用次数暴涨2~3倍!

随着AI领域的迅猛发展&#xff0c;学术成果的传播方式发生了显著转变。 期刊审稿周期长&#xff0c;当你还在和审稿人battle时&#xff0c;方法先过时了。而会议虽然没有期刊长&#xff0c;但也有几个月的时间差&#xff0c;为了保护成果的创新性并扩大影响力&#xff0c;很多…

npm 上传一个自己的应用(3) 在项目中导入及使用自己上传到NPM的工具

上文 npm 上传一个自己的应用(2) 创建一个JavaScript函数 并发布到NPM 我们创建了一个函数 并发上了npm 最后 我们这里 我们可以看到它的安装指令 这里 我们可以打开一个vue项目 终端输入 我们的安装指令 npm i 自己的包 如下代码 npm i grtest我们在 node_modules目录 下…

搭建自己的私服 maven 仓库

申明&#xff1a;本文章所使用docker-compose配置文件纯属学习运用&#xff0c;非商用如有雷同请联系本人协调处理。 一、配置docker-compose.yml文件 # 指定docker-compose的版本 version: 3 services: nexus: container_name: nexus_container image: sonatype/nex…

理解进程的一些知识准备

1. 认识冯诺依曼体系结构 计算机有很多的体系结构&#xff0c;但到如今&#xff0c;冯诺依曼体系结构变成了主流。 输入设备&#xff1a;话筒、键盘、摄像头、鼠标、磁盘、网卡… 输出设备&#xff1a;声卡、显示器、打印机、显卡、网卡、磁盘… 有的设备既能作为输入设备又能…

麒麟信安服务器操作系统荣获 “2023年湖南省软件和信息技术服务业名品”

12月22日&#xff0c;由中国软件行业协会、湖南省工业和信息化厅指导&#xff0c;湖南省软件行业协会、长沙市雨花区政府主办的2023年第五届湖南省软件产业高质量发展大会暨湖南省软件行业协会年会召开。会上隆重揭晓了“2023年湖南软件行业知名软件产品和服务”奖项&#xff0…

【Linux】进程间通信 --管道通信

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 本篇导航 0. 进程间通信原理1. 匿名管道1.1 通信原理1.2 接口介绍 2. 命名管道2.1 接口介绍 3. 共享内存3.1 通信原理3.2 接口介绍 0. 进…

Python类与对象

目录 面向对象 定义类 创建对象 类的成员 实例变量 构造方法 实例方法 类变量 类方法 封装性 私有变量 私有方法 使用属性 继承性 Python中的继承 多继承 方法重写 多态性 继承与多态 鸭子类型测试与多态 面向对象 类和对象都是面向对象中的重要概念。面向…

嵌入式基础知识-组合逻辑与时序逻辑电路

本篇来介绍嵌入式硬件电路的相关知识&#xff1a;组合逻辑电路与时序逻辑电路 根据电路是否具有存储功能&#xff0c;将逻辑电路分为组合逻辑电路和时序逻辑电路。 1 组合逻辑电路 组合逻辑电路&#xff0c;是指在任何时刻&#xff0c;电路的输出状态只取决于同一时刻的输入…