oauth2-令牌使用jwt字符串并且自定义Token数据

x33g5p2x  于2022-04-17 转载在 其他  
字(16.7k)|赞(0)|评价(0)|浏览(268)

1.项目结构图

2.建表语句

  1. DROP TABLE IF EXISTS `oauth_client_details`;
  2. CREATE TABLE `oauth_client_details` (
  3. `client_id` varchar(48) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  4. `resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  5. `client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  6. `scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  7. `authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  8. `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  9. `authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  10. `access_token_validity` int(11) NULL DEFAULT NULL,
  11. `refresh_token_validity` int(11) NULL DEFAULT NULL,
  12. `additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  13. `autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  14. PRIMARY KEY (`client_id`) USING BTREE
  15. ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  16. -- ----------------------------
  17. -- Records of oauth_client_details
  18. -- ----------------------------
  19. INSERT INTO `oauth_client_details` VALUES ('yl', 'res1', '$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO', 'all', 'authorization_code,refresh_token,implicit,password,client_credentials', 'http://localhost:8082/01.html,http://localhost:8082/02.html', NULL, 7200, 7200, NULL, 'true');
  20. SET FOREIGN_KEY_CHECKS = 1;

3.授权服务器的搭建(auth-server)

1.pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.2.5.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.yl</groupId>
  12. <artifactId>auth-server</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>auth-server</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>11</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-web</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-jdbc</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>com.alibaba</groupId>
  30. <artifactId>druid-spring-boot-starter</artifactId>
  31. <version>1.1.10</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>mysql</groupId>
  35. <artifactId>mysql-connector-java</artifactId>
  36. <scope>runtime</scope>
  37. </dependency>
  38. <dependency>
  39. <groupId>org.springframework.boot</groupId>
  40. <artifactId>spring-boot-starter-data-redis</artifactId>
  41. </dependency>
  42. <dependency>
  43. <groupId>org.springframework.cloud</groupId>
  44. <artifactId>spring-cloud-security</artifactId>
  45. <version>2.2.5.RELEASE</version>
  46. </dependency>
  47. <dependency>
  48. <groupId>org.springframework.cloud</groupId>
  49. <artifactId>spring-cloud-starter-oauth2</artifactId>
  50. <version>2.2.5.RELEASE</version>
  51. </dependency>
  52. <dependency>
  53. <groupId>org.springframework.boot</groupId>
  54. <artifactId>spring-boot-starter-test</artifactId>
  55. <scope>test</scope>
  56. </dependency>
  57. </dependencies>
  58. <build>
  59. <plugins>
  60. <plugin>
  61. <groupId>org.springframework.boot</groupId>
  62. <artifactId>spring-boot-maven-plugin</artifactId>
  63. </plugin>
  64. </plugins>
  65. </build>
  66. </project>

2.application.properties

  1. spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
  2. spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
  3. spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
  4. spring.datasource.username=root
  5. spring.datasource.password=root
  6. spring.main.allow-bean-definition-overriding=true
  7. # redis的配置
  8. spring.redis.host=192.168.244.138
  9. spring.redis.port=6379
  10. spring.redis.password=root123
  11. spring.redis.database=0

3.token的配置

  1. package com.yl.authserver.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.data.redis.connection.RedisConnectionFactory;
  6. import org.springframework.security.oauth2.provider.token.TokenStore;
  7. import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
  8. import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
  9. import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
  10. import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
  11. @Configuration
  12. public class AccessTokenConfig {
  13. // 服务端不需要保存jwt的字符串
  14. @Bean
  15. TokenStore tokenStore() {
  16. return new JwtTokenStore(jwtAccessTokenConverter());
  17. }
  18. @Bean
  19. JwtAccessTokenConverter jwtAccessTokenConverter() {
  20. JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
  21. converter.setSigningKey("tom");
  22. return converter;
  23. }
  24. }

4.security的配置

  1. package com.yl.authserver.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.security.authentication.AuthenticationManager;
  5. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  6. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  7. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  8. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  9. import org.springframework.security.crypto.password.PasswordEncoder;
  10. @Configuration
  11. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  12. @Bean
  13. PasswordEncoder passwordEncoder() {
  14. return new BCryptPasswordEncoder();
  15. }
  16. @Bean
  17. @Override
  18. public AuthenticationManager authenticationManagerBean() throws Exception {
  19. return super.authenticationManagerBean();
  20. }
  21. @Override
  22. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  23. auth.inMemoryAuthentication()
  24. .withUser("admin")
  25. .password(passwordEncoder().encode("123"))
  26. .roles("admin")
  27. .and()
  28. .withUser("root")
  29. .password(passwordEncoder().encode("123"))
  30. .roles("root");
  31. }
  32. @Override
  33. protected void configure(HttpSecurity http) throws Exception {
  34. http.csrf().disable().formLogin();
  35. }
  36. }

5.自定义token数据返回的配置

  1. package com.yl.authserver.config;
  2. import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
  3. import org.springframework.security.oauth2.common.OAuth2AccessToken;
  4. import org.springframework.security.oauth2.provider.OAuth2Authentication;
  5. import org.springframework.security.oauth2.provider.token.TokenEnhancer;
  6. import org.springframework.stereotype.Component;
  7. import java.util.Map;
  8. @Component
  9. public class AdditionalInformation implements TokenEnhancer {
  10. @Override
  11. public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {
  12. Map<String, Object> map = oAuth2AccessToken.getAdditionalInformation();
  13. map.put("msg","hello oauth2");
  14. map.put("网站","www.baidu.com");
  15. map.put("微信","66");
  16. ((DefaultOAuth2AccessToken)oAuth2AccessToken).setAdditionalInformation(map);
  17. return oAuth2AccessToken;
  18. }
  19. }

6.授权服务器的配置

  1. package com.yl.authserver.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.security.authentication.AuthenticationManager;
  6. import org.springframework.security.crypto.password.PasswordEncoder;
  7. import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
  8. import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
  9. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
  10. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
  11. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
  12. import org.springframework.security.oauth2.provider.ClientDetailsService;
  13. import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
  14. import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
  15. import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
  16. import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
  17. import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
  18. import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
  19. import org.springframework.security.oauth2.provider.token.TokenStore;
  20. import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
  21. import javax.sql.DataSource;
  22. import java.util.Arrays;
  23. //配置授权服务器
  24. @Configuration
  25. @EnableAuthorizationServer
  26. public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
  27. @Autowired
  28. TokenStore tokenStore;
  29. // 客户端信息
  30. // @Autowired
  31. // ClientDetailsService clientDetailsService;
  32. @Autowired
  33. PasswordEncoder passwordEncoder;
  34. @Autowired
  35. JwtAccessTokenConverter jwtAccessTokenConverter;
  36. @Autowired
  37. AdditionalInformation additionalInformation;
  38. @Autowired
  39. AuthenticationManager authenticationManager;
  40. @Autowired
  41. DataSource dataSource;
  42. @Bean
  43. ClientDetailsService clientDetailsService() {
  44. return new JdbcClientDetailsService(dataSource);
  45. }
  46. //配置Token服务
  47. AuthorizationServerTokenServices authorizationServerTokenServices() {
  48. DefaultTokenServices tokenServices = new DefaultTokenServices();
  49. tokenServices.setClientDetailsService(clientDetailsService());
  50. tokenServices.setSupportRefreshToken(true);
  51. tokenServices.setAccessTokenValiditySeconds(60 * 60 * 2); //token有限期设置为2小时
  52. tokenServices.setRefreshTokenValiditySeconds(60 * 60 * 24 * 7);
  53. tokenServices.setTokenStore(tokenStore);
  54. TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
  55. tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter,additionalInformation));
  56. tokenServices.setTokenEnhancer(tokenEnhancerChain);
  57. return tokenServices;
  58. }
  59. //配置token
  60. @Override
  61. public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
  62. security.checkTokenAccess("permitAll()")// /oauth/check_token 带时候会调用这个请求来校验token
  63. .checkTokenAccess("isAuthenticated()")
  64. .allowFormAuthenticationForClients();
  65. }
  66. //配置客户端的信息(客户端信息存于内存)
  67. // @Override
  68. // public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  69. // clients.inMemory()
  70. // .withClient("yl") //客户端名
  71. // .secret(passwordEncoder.encode("123")) //客户端密码
  72. // .scopes("all")
  73. // .resourceIds("res1") //资源id
  74. // .authorizedGrantTypes("authorization_code","refresh_token","implicit","password","client_credentials")
  75. // // authorization_code授权码模式,password密码模式,implicit简化模式,client_credentials客户端模式,可以设置同时支持多种模式
  76. // .autoApprove(true) //自动授权
  77. .redirectUris("http://localhost:8082/index.html"); //授权码模式界面
  78. .redirectUris("http://localhost:8082/01.html");//简化模式界面
  79. // .redirectUris("http://localhost:8082/02.html");//密码模式界面
  80. // }
  81. //配置客户端的信息(客户端信息存于数据库)
  82. @Override
  83. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  84. clients.withClientDetails(clientDetailsService());
  85. }
  86. //配置端点信息(主要获取授权码,要先拿到授权码,然后再根据授权码去获取token)
  87. @Override
  88. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  89. endpoints.authorizationCodeServices(authorizationCodeServices())
  90. .authenticationManager(authenticationManager)
  91. .tokenServices(authorizationServerTokenServices());
  92. }
  93. @Bean
  94. AuthorizationCodeServices authorizationCodeServices() {
  95. return new InMemoryAuthorizationCodeServices();
  96. }
  97. }

4. 资源服务器的搭建(user-server)

1.pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.2.5.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.yl</groupId>
  12. <artifactId>user-server</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>user-server</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>11</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-web</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.cloud</groupId>
  26. <artifactId>spring-cloud-security</artifactId>
  27. <version>2.2.5.RELEASE</version>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework.cloud</groupId>
  31. <artifactId>spring-cloud-starter-oauth2</artifactId>
  32. <version>2.2.5.RELEASE</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.springframework.boot</groupId>
  36. <artifactId>spring-boot-starter-test</artifactId>
  37. <scope>test</scope>
  38. </dependency>
  39. </dependencies>
  40. <build>
  41. <plugins>
  42. <plugin>
  43. <groupId>org.springframework.boot</groupId>
  44. <artifactId>spring-boot-maven-plugin</artifactId>
  45. </plugin>
  46. </plugins>
  47. </build>
  48. </project>

2.application.properties

  1. server.port=8081

3.contoller

  1. package com.yl.userserver.controller;
  2. import org.springframework.web.bind.annotation.CrossOrigin;
  3. import org.springframework.web.bind.annotation.GetMapping;
  4. import org.springframework.web.bind.annotation.RestController;
  5. @RestController
  6. @CrossOrigin(value = "*")
  7. public class HelloController {
  8. @GetMapping("/hello")
  9. public String hello() {
  10. return "hello";
  11. }
  12. @GetMapping("/admin")
  13. public String admin() {
  14. return "hello admin";
  15. }
  16. }

4.token的配置

  1. package com.yl.userserver.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.security.oauth2.provider.token.TokenStore;
  5. import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
  6. import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
  7. @Configuration
  8. public class AccessTokenConfig {
  9. // 服务端不需要保存jwt的字符串
  10. @Bean
  11. TokenStore tokenStore() {
  12. return new JwtTokenStore(jwtAccessTokenConverter());
  13. }
  14. @Bean
  15. JwtAccessTokenConverter jwtAccessTokenConverter() {
  16. JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
  17. converter.setSigningKey("tom");
  18. return converter;
  19. }
  20. }

5.资源服务器的配置

  1. package com.yl.userserver.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  6. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
  7. import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
  8. import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
  9. import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
  10. import org.springframework.security.oauth2.provider.token.TokenStore;
  11. //配置资源服务器
  12. @Configuration
  13. @EnableResourceServer
  14. public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
  15. @Autowired
  16. TokenStore tokenStore;
  17. @Override
  18. public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
  19. resources.resourceId("res1")
  20. .tokenStore(tokenStore)
  21. .stateless(true);
  22. }
  23. @Override
  24. public void configure(HttpSecurity http) throws Exception {
  25. http.authorizeRequests()
  26. .antMatchers("/admin/**")
  27. .hasRole("admin")
  28. .anyRequest().authenticated()
  29. .and().cors();
  30. }
  31. }

5. 测试

1.启动redis
2.启动授权服务器和资源服务器
3.获取token

4.携带token访问资源服务器的hello接口

相关文章