当前位置: 首页 > news >正文

基于Spring cloud搭建oauth2

1,OAuth2.0简介

OAuth(开发授权)是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容。
OAuth2.0是OAuth的延续,但他并不兼容OAuth1.0,即它完全废除OAuth1.0。很多大公司如Google,Yahoo,Microsoft等都提供了OAuth认证服 务,这些都足以说明OAUTH标准逐渐成为开放资源授权的标准。
微信小程序授权登录同样也是提供OAuth认证服务。详情请看

2,业务场景

某一天你想登录网站CSDN,之前没有在CSDN网站注册过,此时在人家的登陆页面提供了其他登录方式,如下图
在这里插入图片描述

假设我们自己做的网站叫网站B,也在上图中红框部分,如下图
在这里插入图片描述

你恰好之前在我们的B网站上注册过账号,那么现在就可以使用B网站上的账号登录在CSDN上。那么我们在B网站上做这样的一个功能就是使用OAuth2做的。

OAuth2.0包含一下几种角色

  • 1,客户端:本身不存储资源,需要通过资源拥有者的授权去请求资源服务器的资源。
  • 2,资源拥有者:通常为用户,也可以是应用程序,即该资源的拥有者。
  • 3,授权服务器(认证服务器):用于服务提供商对资源拥有者的身份认证,对访问资源进行授权,认证成功后会给客户端发放令牌(access_token),作为客户端访问资源服务器的凭据。
  • 4,资源服务器:存储资源的服务器
  • 5,客户端标识:client_id
  • 6,客户端密钥:client_secret
    为什么要有client_id和client_secret呢?
    因为服务提供商不能允许随便一个客户端就接入到它的授权服务器,服务提供商会 给准入的接入方一个身份,用于接入时的凭据。

3,环境搭建

在这里插入图片描述

authServer-service 认证服务(颁发Token)

gateway-service 网关(认证用户的请求 也即认证Token)

member-service 会员服务(资源服务)

在这里插入图片描述

5,环境搭建

父工程pom

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>shop.awz</groupId><artifactId>rwShop</artifactId><version>1.0-SNAPSHOT</version><modules><module>authServer-service</module><module>gateway-service</module><module>order-service</module><module>authServer-service</module><module>admin-service</module><module>product-service</module><module>common-service</module></modules><packaging>pom</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-parent</artifactId><version>2.3.2.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF‐8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF‐8</project.reporting.outputEncoding><java.version>1.8</java.version><maven.compiler.source>1.7</maven.compiler.source><maven.compiler.target>1.7</maven.compiler.target><spring.cloud-version>Hoxton.SR9</spring.cloud-version></properties><dependencies><!--服务注册发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud-version}</version><type>pom</type><scope>import</scope></dependency><!--spring-cloud-alibaba 版本控制--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.6.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-jar-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin><!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --><plugin><artifactId>maven-site-plugin</artifactId><version>3.7.1</version></plugin><plugin><artifactId>maven-project-info-reports-plugin</artifactId><version>3.0.0</version></plugin></plugins></pluginManagement></build>
</project>

authServer-service 工程pom

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>rwShop</artifactId><groupId>shop.awz</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>authServer-service</artifactId><name>authServer-service</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.7</maven.compiler.source><maven.compiler.target>1.7</maven.compiler.target></properties><dependencies><!--Lombok引入--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- Spring Boot JPA 依赖 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.0</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><!--可以把依赖的包都打包到生成的Jar包中--><goal>repackage</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>
</project>

网关pom

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>rwShop</artifactId><groupId>shop.awz</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>gateway-service</artifactId><name>gateway-service</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.7</maven.compiler.source><maven.compiler.target>1.7</maven.compiler.target><spring.cloud-version>Hoxton.SR9</spring.cloud-version></properties><dependencies><!--安全认证框架--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!--security-oauth2整合--><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-resource-server</artifactId></dependency><!--oauth2--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency></dependencies><dependencyManagement><!--https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E--><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring.cloud-version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><!--可以把依赖的包都打包到生成的Jar包中--><goal>repackage</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>
</project>

4,authServer-service

sql脚本
DROP TABLE IF EXISTS `oauth_refresh_token`;
CREATE TABLE `oauth_refresh_token`  (`token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`token` blob NULL,`authentication` blob NULL
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of oauth_refresh_token
-- ----------------------------
INSERT INTO `oauth_refresh_token` VALUES ('bbd20d647aae14322d441c3bfee18d03', 0xACED00057372004C6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744578706972696E674F417574683252656672657368546F6B656E2FDF47639DD0C9B70200014C000A65787069726174696F6E7400104C6A6176612F7574696C2F446174653B787200446F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744F417574683252656672657368546F6B656E73E10E0A6354D45E0200014C000576616C75657400124C6A6176612F6C616E672F537472696E673B787074002438396463643534612D626663392D343964352D613332372D3834653637643030656630637372000E6A6176612E7574696C2E44617465686A81014B5974190300007870770800000186CF2F197E78, 0xACED0005737200416F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F417574683241757468656E7469636174696F6EBD400B02166252130200024C000D73746F7265645265717565737474003C4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F4F4175746832526571756573743B4C00127573657241757468656E7469636174696F6E7400324C6F72672F737072696E676672616D65776F726B2F73656375726974792F636F72652F41757468656E7469636174696F6E3B787200476F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E416273747261637441757468656E7469636174696F6E546F6B656ED3AA287E6E47640E0200035A000D61757468656E746963617465644C000B617574686F7269746965737400164C6A6176612F7574696C2F436F6C6C656374696F6E3B4C000764657461696C737400124C6A6176612F6C616E672F4F626A6563743B787000737200266A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654C697374FC0F2531B5EC8E100200014C00046C6973747400104C6A6176612F7574696C2F4C6973743B7872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C00016371007E00047870737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A65787000000001770400000001737200426F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E617574686F726974792E53696D706C654772616E746564417574686F7269747900000000000002120200014C0004726F6C657400124C6A6176612F6C616E672F537472696E673B787074003C24326124313024397A6D7A72516F485065324C76552F6369594F6837656830767054686C47306A66566E643935742F4D634C794C623974354E337A477871007E000C707372003A6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F41757468325265717565737400000000000000010200075A0008617070726F7665644C000B617574686F72697469657371007E00044C000A657874656E73696F6E7374000F4C6A6176612F7574696C2F4D61703B4C000B726564697265637455726971007E000E4C00077265667265736874003B4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F546F6B656E526571756573743B4C000B7265736F7572636549647374000F4C6A6176612F7574696C2F5365743B4C000D726573706F6E7365547970657371007E0014787200386F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E426173655265717565737436287A3EA37169BD0200034C0008636C69656E74496471007E000E4C001172657175657374506172616D657465727371007E00124C000573636F706571007E00147870740003617070737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654D6170F1A5A8FE74F507420200014C00016D71007E00127870737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F400000000000067708000000080000000374000A6772616E745F7479706574000870617373776F7264740009636C69656E745F6964740003617070740008757365726E616D657400047A69796178737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65536574801D92D18F9B80550200007871007E0009737200176A6176612E7574696C2E4C696E6B656448617368536574D86CD75A95DD2A1E020000787200116A6176612E7574696C2E48617368536574BA44859596B8B7340300007870770C000000103F4000000000000174000377656278017371007E0025770C000000103F400000000000017371007E000D740009524F4C455F55534552787371007E001A3F40000000000000770800000010000000007870707371007E0025770C000000103F40000000000001740003617070787371007E0025770C000000103F40000000000000787372004F6F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E557365726E616D6550617373776F726441757468656E7469636174696F6E546F6B656E00000000000002120200024C000B63726564656E7469616C7371007E00054C00097072696E636970616C71007E00057871007E0003017371007E00077371007E000B0000000177040000000171007E000F7871007E0032737200176A6176612E7574696C2E4C696E6B6564486173684D617034C04E5C106CC0FB0200015A000B6163636573734F726465727871007E001A3F400000000000067708000000080000000474000D636C69656E745F73656372657474000361707071007E001C71007E001D71007E001E71007E001F71007E002071007E0021780070737200326F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E7573657264657461696C732E5573657200000000000002120200075A00116163636F756E744E6F6E457870697265645A00106163636F756E744E6F6E4C6F636B65645A001563726564656E7469616C734E6F6E457870697265645A0007656E61626C65644C000B617574686F72697469657371007E00144C000870617373776F726471007E000E4C0008757365726E616D6571007E000E7870010101017371007E0022737200116A6176612E7574696C2E54726565536574DD98509395ED875B0300007870737200466F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E7573657264657461696C732E5573657224417574686F72697479436F6D70617261746F720000000000000212020000787077040000000171007E000F78707400047A697961);SET FOREIGN_KEY_CHECKS = 1;DROP TABLE IF EXISTS `oauth_access_token`;
CREATE TABLE `oauth_access_token`  (`token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`token` blob NULL,`authentication_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`user_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`authentication` blob NULL,`refresh_token` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of oauth_access_token
-- ----------------------------
INSERT INTO `oauth_access_token` VALUES ('5e45bb16fc49de6fbdbbc5272cf199f7', 0xACED0005737200436F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744F4175746832416363657373546F6B656E0CB29E361B24FACE0200064C00156164646974696F6E616C496E666F726D6174696F6E74000F4C6A6176612F7574696C2F4D61703B4C000A65787069726174696F6E7400104C6A6176612F7574696C2F446174653B4C000C72656672657368546F6B656E74003F4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F636F6D6D6F6E2F4F417574683252656672657368546F6B656E3B4C000573636F706574000F4C6A6176612F7574696C2F5365743B4C0009746F6B656E547970657400124C6A6176612F6C616E672F537472696E673B4C000576616C756571007E000578707372001E6A6176612E7574696C2E436F6C6C656374696F6E7324456D7074794D6170593614855ADCE7D002000078707372000E6A6176612E7574696C2E44617465686A81014B597419030000787077080000018637437F9E787372004C6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744578706972696E674F417574683252656672657368546F6B656E2FDF47639DD0C9B70200014C000A65787069726174696F6E71007E0002787200446F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744F417574683252656672657368546F6B656E73E10E0A6354D45E0200014C000576616C756571007E0005787074002438396463643534612D626663392D343964352D613332372D3834653637643030656630637371007E0009770800000186CF2F197E78737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65536574801D92D18F9B80550200007872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C0001637400164C6A6176612F7574696C2F436F6C6C656374696F6E3B7870737200176A6176612E7574696C2E4C696E6B656448617368536574D86CD75A95DD2A1E020000787200116A6176612E7574696C2E48617368536574BA44859596B8B7340300007870770C000000103F400000000000017400037765627874000662656172657274002433633033643735392D376665362D346164322D383034332D303066303564366466353066, '743b6d0443f74879a092610739f759b6', 'ziya', 'app', 0xACED0005737200416F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F417574683241757468656E7469636174696F6EBD400B02166252130200024C000D73746F7265645265717565737474003C4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F4F4175746832526571756573743B4C00127573657241757468656E7469636174696F6E7400324C6F72672F737072696E676672616D65776F726B2F73656375726974792F636F72652F41757468656E7469636174696F6E3B787200476F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E416273747261637441757468656E7469636174696F6E546F6B656ED3AA287E6E47640E0200035A000D61757468656E746963617465644C000B617574686F7269746965737400164C6A6176612F7574696C2F436F6C6C656374696F6E3B4C000764657461696C737400124C6A6176612F6C616E672F4F626A6563743B787000737200266A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654C697374FC0F2531B5EC8E100200014C00046C6973747400104C6A6176612F7574696C2F4C6973743B7872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C00016371007E00047870737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A65787000000001770400000001737200426F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E617574686F726974792E53696D706C654772616E746564417574686F7269747900000000000002120200014C0004726F6C657400124C6A6176612F6C616E672F537472696E673B787074003C24326124313024397A6D7A72516F485065324C76552F6369594F6837656830767054686C47306A66566E643935742F4D634C794C623974354E337A477871007E000C707372003A6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F41757468325265717565737400000000000000010200075A0008617070726F7665644C000B617574686F72697469657371007E00044C000A657874656E73696F6E7374000F4C6A6176612F7574696C2F4D61703B4C000B726564697265637455726971007E000E4C00077265667265736874003B4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F546F6B656E526571756573743B4C000B7265736F7572636549647374000F4C6A6176612F7574696C2F5365743B4C000D726573706F6E7365547970657371007E0014787200386F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E426173655265717565737436287A3EA37169BD0200034C0008636C69656E74496471007E000E4C001172657175657374506172616D657465727371007E00124C000573636F706571007E00147870740003617070737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654D6170F1A5A8FE74F507420200014C00016D71007E00127870737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F400000000000067708000000080000000374000A6772616E745F7479706574000870617373776F7264740009636C69656E745F6964740003617070740008757365726E616D657400047A69796178737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65536574801D92D18F9B80550200007871007E0009737200176A6176612E7574696C2E4C696E6B656448617368536574D86CD75A95DD2A1E020000787200116A6176612E7574696C2E48617368536574BA44859596B8B7340300007870770C000000103F4000000000000174000377656278017371007E0025770C000000103F400000000000017371007E000D740009524F4C455F55534552787371007E001A3F40000000000000770800000010000000007870707371007E0025770C000000103F40000000000001740003617070787371007E0025770C000000103F40000000000000787372004F6F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E557365726E616D6550617373776F726441757468656E7469636174696F6E546F6B656E00000000000002120200024C000B63726564656E7469616C7371007E00054C00097072696E636970616C71007E00057871007E0003017371007E00077371007E000B0000000177040000000171007E000F7871007E0032737200176A6176612E7574696C2E4C696E6B6564486173684D617034C04E5C106CC0FB0200015A000B6163636573734F726465727871007E001A3F400000000000067708000000080000000474000D636C69656E745F73656372657474000361707071007E001C71007E001D71007E001E71007E001F71007E002071007E0021780070737200326F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E7573657264657461696C732E5573657200000000000002120200075A00116163636F756E744E6F6E457870697265645A00106163636F756E744E6F6E4C6F636B65645A001563726564656E7469616C734E6F6E457870697265645A0007656E61626C65644C000B617574686F72697469657371007E00144C000870617373776F726471007E000E4C0008757365726E616D6571007E000E7870010101017371007E0022737200116A6176612E7574696C2E54726565536574DD98509395ED875B0300007870737200466F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E7573657264657461696C732E5573657224417574686F72697479436F6D70617261746F720000000000000212020000787077040000000171007E000F78707400047A697961, 'bbd20d647aae14322d441c3bfee18d03');SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details`  (`client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`access_token_validity` int NULL DEFAULT NULL,`refresh_token_validity` int NULL DEFAULT NULL,`additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of oauth_client_details
-- ----------------------------
INSERT INTO `oauth_client_details` VALUES ('app', 'app', '$2a$10$by3F74LZAxBQLXCbESOS/eew8/7skdxvx5QdcJAMddfLISizAOXAe', 'web', 'implicit,client_credentials,authorization_code,refresh_token,password', 'http://www.baidu.com', 'ROLE_USER', NULL, NULL, NULL, NULL);SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE IF EXISTS `oauth_client_token`;
CREATE TABLE `oauth_client_token`  (`token_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`token` blob NULL,`authentication_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`user_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`authentication_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of oauth_client_token
-- ----------------------------SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE IF EXISTS `oauth_code`;
CREATE TABLE `oauth_code`  (`code` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`authentication` blob NULL
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of oauth_code
-- ----------------------------SET FOREIGN_KEY_CHECKS = 1;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (`id` int NOT NULL AUTO_INCREMENT,`passwd` varchar(265) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`user_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`user_role` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '$2a$10$9zmzrQoHPe2LvU/ciYOh7eh0vpThlG0jfVnd95t/McLyLb9t5N3zG', 'ziya', 'ADMIN');SET FOREIGN_KEY_CHECKS = 1;

配置文件application.yml

server:port: 9000spring:main:allow-bean-definition-overriding: trueapplication:name: auth-servicedatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/awz_admins?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf8username: rootpassword: 123456jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8cloud:nacos:discovery:server-addr: 127.0.0.1:8848
logging:level:shop.awz.uaa.dao: debug
#  file:
#    name: log/blog.logpattern:level:mybatis-plus:type-aliases-package: shop.awz.uaa.entitymapper-locations: classpath:mapper/*.xml#配置驼峰命名映射configuration:map-underscore-to-camel-case: true

AuthorizationServerConfig配置类


```java
package shop.awz.uaa.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;import javax.sql.DataSource;
import java.util.Arrays;/*** @ClassName AuthorizationServerConfig* @Author 杨杰* @Date 2023/2/9 12:15* @Version 1.0*/@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {@Autowiredprivate UserDetailsService userDetailService;// 认证管理器@Autowiredprivate AuthenticationManager authenticationManager;@Autowiredprivate DataSource dataSource;@Autowiredprivate JwtAccessTokenConverter accessTokenConverter;@Autowiredprivate TokenStore tokenStore;@Autowiredprivate ClientDetailsService clientDetailsService;//令牌管理服务@Beanpublic AuthorizationServerTokenServices tokenService() {DefaultTokenServices service = new DefaultTokenServices();// 客户端详情服务service.setClientDetailsService(clientDetailsService);service.setSupportRefreshToken(true);//支持刷新令牌service.setTokenStore(tokenStore);//令牌存储策略//令牌增强TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));service.setTokenEnhancer(tokenEnhancerChain);service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天return service;}//    /**
//     * access_token存储器
//     * 这里存储在数据库,大家可以结合自己的业务场景考虑将access_token存入数据库还是redis
//     */
//    @Bean
//    public TokenStore tokenStore() {
//        return new JdbcTokenStore(dataSource);
//    }/*** 从数据库读取clientDetails相关配置* 有InMemoryClientDetailsService 和 JdbcClientDetailsService 两种方式选择*/@Beanpublic ClientDetailsService clientDetails() {return new JdbcClientDetailsService(dataSource);}/*** 注入密码加密实现器*/@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}/*** 认证服务器Endpoints配置*/@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {//如果需要使用refresh_token模式则需要注入userDetailServiceendpoints.userDetailsService(userDetailService);endpoints.authenticationManager(this.authenticationManager);endpoints.tokenServices(tokenService());endpoints.tokenStore(tokenStore);}/*** 认证服务器相关接口权限管理*/@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security.allowFormAuthenticationForClients() //如果使用表单认证则需要加上.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");}/*** client存储方式,此处使用jdbc存储*/@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.withClientDetails(clientDetails());}
}

ClientDetailsServiceConfigurer:用来配置客户端详情服务(ClientDetailsService),客户端详情信息在 这里进行初始化,你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息。AuthorizationServerEndpointsConfigurer:用来配置令牌(token)的访问端点和令牌服务(token services)。AuthorizationServerSecurityConfigurer:用来配置令牌端点的安全约束
TokenConfig配置类```java
package shop.awz.uaa.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;/*** @ClassName TokenConfig* @Author 杨杰* @Date 2023/2/9 22:14* @Version 1.0*/
@Configuration
public class TokenConfig {private String SIGNING_KEY = "uaa123";@Beanpublic TokenStore tokenStore() {//JWT令牌存储方案return new JwtTokenStore(accessTokenConverter());}@Beanpublic JwtAccessTokenConverter accessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter.setSigningKey(SIGNING_KEY); //对称秘钥,资源服务器使用该秘钥来验证return converter;}/* @Beanpublic TokenStore tokenStore() {//使用内存存储令牌(普通令牌)return new InMemoryTokenStore();}*/
}

这里使用的是JWT
WebSecurityConfig配置类

package shop.awz.uaa.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import shop.awz.uaa.service.UserDetailServiceImpl;
/*** @ClassName WebSecurityConfig* @Author 杨杰* @Date 2023/2/9 12:25* @Version 1.0*/@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Override@Bean("UserDetailServiceImpl")public UserDetailsService userDetailsService(){return new UserDetailServiceImpl();}@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}/*** 认证管理* @return 认证管理对象* @throws Exception 认证异常信息*/@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService()).passwordEncoder(new PasswordEncoder() {//密码加密@Overridepublic String encode(CharSequence charSequence) {BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();return passwordEncoder.encode(charSequence);}@Overridepublic boolean matches(CharSequence charSequence, String s) {BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();boolean res = passwordEncoder.matches(charSequence, s);return res;}});}/*** http安全配置* @param http http安全对象* @throws Exception http安全异常信息*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().httpBasic().and().cors().and().csrf().disable();}@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/error","/static/**","/v2/api-docs/**","/swagger-resources/**","/webjars/**","/favicon.ico");}
}

UserDetailServiceImpl实现类

package shop.awz.uaa.service;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import shop.awz.uaa.dao.UserMapper;
import shop.awz.uaa.entity.User;/*** @ClassName UserDetailServiceImpl* @Author 杨杰* @Date 2023/2/9 12:11* @Version 1.0*/
@Service("UserDetailServiceImpl")
public class UserDetailServiceImpl implements UserDetailsService {@Autowiredprivate UserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {//获取本地用户
//        User user = userName.queryByUserName(userName);User user = userMapper.selectOne(new QueryWrapper<User>().eq("user_name",userName));if (user != null) {//返回oauth2的用户return new org.springframework.security.core.userdetails.User(user.getUserName(),user.getPasswd(),AuthorityUtils.createAuthorityList(user.getPasswd()));} else {throw new UsernameNotFoundException("用户[" + userName + "]不存在");}}
}

user实体类

package shop.awz.uaa.entity;/*** @ClassName User* @Author 杨杰* @Date 2023/2/9 11:59* @Version 1.0*/import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("user")
public class User {@TableIdprivate Integer id;private String passwd;private String userName;private String userRole;}

usermapper

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

启动类

@SpringBootApplication
@EnableResourceServer
@EnableDiscoveryClient
public class AuthServiceMain9000
{public static void main( String[] args ){SpringApplication.run(AuthServiceMain9000.class,args);}
}

6,网关

application.ymlserver:port: 80spring:application:name: gateway-servicedatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/awz_admins?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf8username: rootpassword: 123456jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8cloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:routes:- id: auth-routeuri: lb://auth-servicepredicates:- Path=/oauth/**- id: order-routeuri: lb://order-servicepredicates:- Path=/order/**- id: admin-routeuri: lb://admin-servicepredicates:- Path=/admin-service/**globalcors:cors-configurations:'[/**]':allow-credentials: trueallowed-methods: "*"allowed-origins: "*"allowed-headers: "*"

TokenConfig配置类

@Configuration
public class TokenConfig {private String SIGNING_KEY = "uaa123";@Beanpublic TokenStore tokenStore() {//JWT令牌存储方案return new JwtTokenStore(accessTokenConverter());}@Beanpublic JwtAccessTokenConverter accessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter.setSigningKey(SIGNING_KEY); //对称秘钥,资源服务器使用该秘钥来验证return converter;}/* @Beanpublic TokenStore tokenStore() {//使用内存存储令牌(普通令牌)return new InMemoryTokenStore();}*/
}

securityConfig配置类

package shop.awz.gateway.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
import shop.awz.gateway.Manager.AccessManager;
import shop.awz.gateway.Manager.ReactiveJdbcAuthenticationManager;import javax.sql.DataSource;/*** @ClassName SecurityConfig* @Author 杨杰* @Date 2023/2/9 12:38* @Version 1.0*/
@Configuration
public class SecurityConfig {private static final String MAX_AGE = "18000L";@Autowiredprivate DataSource dataSource;@Autowiredprivate AccessManager accessManager;@Autowiredprivate TokenStore tokenStore;@BeanSecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception{//token管理器ReactiveAuthenticationManager tokenAuthenticationManager = new ReactiveJdbcAuthenticationManager(tokenStore);//认证过滤器AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(tokenAuthenticationManager);authenticationWebFilter.setServerAuthenticationConverter(new ServerBearerTokenAuthenticationConverter());http.httpBasic().disable().csrf().disable().authorizeExchange().pathMatchers(HttpMethod.OPTIONS).permitAll().pathMatchers(HttpMethod.GET).permitAll().pathMatchers(HttpMethod.POST).permitAll().anyExchange().access(accessManager).and()//oauth2认证过滤器.addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION);return http.build();}
}

AccessManager配置类

package shop.awz.gateway.Manager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.web.server.authorization.AuthorizationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;/*** @ClassName AccessManager* @Author 杨杰* @Date 2023/2/9 12:37* @Version 1.0*/@Slf4j
@Component
public class AccessManager implements ReactiveAuthorizationManager<AuthorizationContext> {private Set<String> permitAll = new ConcurrentSkipListSet<>();private static final AntPathMatcher antPathMatcher = new AntPathMatcher();public AccessManager() {permitAll.add("/");permitAll.add("/error");permitAll.add("/favicon.ico");permitAll.add("/**/v2/api-docs/**");permitAll.add("/**/swagger-resources/**");permitAll.add("/webjars/**");permitAll.add("/doc.html");permitAll.add("/swagger-ui.html");permitAll.add("/**/oauth/**");permitAll.add("/**/current/get");permitAll.add("/admin-service/**");}/*** 实现权限验证判断*/@Overridepublic Mono<AuthorizationDecision> check(Mono<Authentication> authenticationMono, AuthorizationContext authorizationContext) {ServerWebExchange exchange = authorizationContext.getExchange();//请求资源String requestPath = exchange.getRequest().getURI().getPath();// 是否直接放行if (permitAll(requestPath)) {return Mono.just(new AuthorizationDecision(true));}return authenticationMono.map(auth -> {return new AuthorizationDecision(checkAuthorities(exchange, auth, requestPath));}).defaultIfEmpty(new AuthorizationDecision(false));}/*** 校验是否属于静态资源** @param requestPath 请求路径* @return*/private boolean permitAll(String requestPath) {return permitAll.stream().filter(r -> antPathMatcher.match(r, requestPath)).findFirst().isPresent();}//权限校验private boolean checkAuthorities(ServerWebExchange exchange, Authentication auth, String requestPath) {if (auth instanceof OAuth2Authentication) {OAuth2Authentication athentication = (OAuth2Authentication) auth;String clientId = athentication.getOAuth2Request().getClientId();log.info("clientId is {}", clientId);}Object principal = auth.getPrincipal();log.info("用户信息:{}", principal.toString());return true;}
}

拦截器配置类

package shop.awz.gateway.Manager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import reactor.core.publisher.Mono;/*** @ClassName ReactiveJdbcAuthenticationManager* @Author 杨杰* @Date 2023/2/9 12:37* @Version 1.0*/public class ReactiveJdbcAuthenticationManager implements ReactiveAuthenticationManager {Logger logger= LoggerFactory.getLogger(ReactiveJdbcAuthenticationManager.class);private TokenStore tokenStore;public ReactiveJdbcAuthenticationManager(TokenStore tokenStore){this.tokenStore = tokenStore;}@Overridepublic Mono<Authentication> authenticate(Authentication authentication) {return Mono.justOrEmpty(authentication).filter(a -> a instanceof BearerTokenAuthenticationToken).cast(BearerTokenAuthenticationToken.class).map(BearerTokenAuthenticationToken::getToken).flatMap((accessToken ->{logger.info("accessToken is :{}",accessToken);OAuth2AccessToken oAuth2AccessToken = this.tokenStore.readAccessToken(accessToken);//根据access_token从数据库获取不到OAuth2AccessTokenif(oAuth2AccessToken == null){return Mono.error(new InvalidTokenException("invalid access token,please check"));}else if(oAuth2AccessToken.isExpired()){return Mono.error(new InvalidTokenException("access token has expired,please reacquire token"));}OAuth2Authentication oAuth2Authentication =this.tokenStore.readAuthentication(accessToken);if(oAuth2Authentication == null){return Mono.error(new InvalidTokenException("Access Token 无效!"));}else {return Mono.just(oAuth2Authentication);}})).cast(Authentication.class);}
}

启动类

@SpringBootApplication
@EnableDiscoveryClient
public class GateWayServiceMain80
{public static void main( String[] args ){SpringApplication.run(GateWayServiceMain80.class,args);}
}
               6,member-service
@GetMapping("/product/{productId}")
public String getProductName(@PathVariable Integer productId) {return "用户基本信息";
}
                          6,测试

在测试之前我们再来梳理一下流程

在这里插入图片描述

1,用户想要登录CSDN,

2,用户在CSDN上选择我们的网站B进行快捷登录(此时我们的网站B已经和CSDN有合作,并且给我们网站B给CSND密钥。和客户端ID)

3,当用户选择后跳转到我们的网站B的第三方授权登录页面,

4,用户输入用户名或密码进行授权登录

5,用户请求携带用户名和密码以及CSDN客户端的ID密钥等信息在我们的网站B上进行登录

6,网关断言后将请求分到授权服务

7,授权服务认证通过后响应授权码到网关

8,网关响应授权码并重定向到CSDN

9,CSDN获取授权码,并携带授权码,再次请求我们的网站B以获取access_token

这里我们为什么要获取access_token?这是因为你要获取的用户信息接口,需要校验这个请求中是否包含access_token,来判断是否是合法请求,这也是Oauth2协议的一个关键部分。之前的是授权码,仅仅代表用户已经同意CSDN网站从我们的网站B上获取他的一些基本信息。而要获取到用户的信息,还必须要有access_token。

10,网关断言后将请求分到授权服务,

11,授权服务通过后,响应access_token给网关

12,网关将access_token响应给CSDN

13,CSDN携带access_token再次请求我们的网站B

14,网关认证(认证access_token是否合法,是否过期等)后,将请求分发到资源服务器

15,资源服务器将用户信息响应给网关

16,网关将用户信息响应给CSDN,

17,CSDN就可以使用这些基本信息来登录

其中1-4部分用户是可以感知的,其余的用户无法感知。

测试:因为我们的网站还无法提供给CSDN做快捷登录

所以我们的模拟只能从9步开始,使用密码登录模式,使用postman进行测试

图片

在这里插入图片描述

相关文章:

基于Spring cloud搭建oauth2

1&#xff0c;OAuth2.0简介 OAuth&#xff08;开发授权&#xff09;是一个开放标准&#xff0c;允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息&#xff0c;而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容。 OAuth2.0是OAuth的延续&#xf…...

实现一个小程序分享图 wxml2canvas

我们经常会遇上动态生成海报的需求&#xff0c;而在小程序中&#xff0c;生成图片非Canvas莫属。但是在实际工作当中&#xff0c;为了追求效率&#xff0c;我们会不可避免地去使用一些JS插件&#xff0c;而 wxml-to-canvas 就是一款官方推荐且非常优秀的插件&#xff0c;它可以…...

基于matlab设计x波段机载SAR系统

一、前言此示例说明如何设计在 X 波段工作的合成孔径雷达 &#xff08;SAR&#xff09; 传感器并计算传感器参数。SAR利用雷达天线在目标区域上的运动来提供目标区域的图像。当SAR平台在目标区域上空行进时&#xff0c;当脉冲从雷达天线发送和接收时&#xff0c;会产生合成孔径…...

WPF学习:Slider — 冒泡显示值

想做一个下图所示的Slider&#xff0c;以冒泡的方式显示其Value值&#xff0c;该怎么做呢&#xff1f; 功能要求&#xff0c;当鼠标放在滑块上的时候&#xff0c;冒“泡”显示值&#xff1b;当滑块移动的时候&#xff0c;“泡”跟随移动。 看似简单的功能&#xff0c;但要完美…...

Vue实战第4章:主页设计之中部内容设计

前言 本篇在讲什么 接上篇文章&#xff0c;我们制作了一个自定义的网页导航栏&#xff0c;本篇文章我们简单制作一个内容页 仅介绍简单的应用&#xff0c;仅供参考 本篇适合什么 适合初学Vue的小白 适合想要自己搭建网站的新手 适合没有接触过vue-router的前端程序 本篇…...

数据结构代码总结(C语言实现)

目录如何应对数据结构的代码题&#xff1f;采取的学习流程①首先对C语言的语法的熟悉②学习掌握基本代码的写法&#xff0c;做到熟练2.1插入排序2.2快速排序2.3二分查找2.4树的遍历③跟着网上视频开始熟悉对一些问题的解答④结合真题的代码&#xff0c;寻找其中的结题规律如何应…...

zookeeper 复习 ---- chapter04

zookeeper 复习 ---- chapter04zookeeper 的精髓是什么&#xff1f; 1&#xff1a;它有四个节点类型 持久无序的节点 临时无序的节点 持久有序的节点 临时有序的节点 临时的节点的特征&#xff1a;当客户端和服务器端断开连接&#xff0c;当前客户端创建的节点被服务器端自动删…...

thinkphp6.0连接MYSQL

目录8.连接多个数据库7.多级控制器不存在6.分页5.非法请求4.关于路由**3.初体验页面****2.加入fileheader添加注释****1.配置mysql0. 官方开发手册一些网址 http://127.0.0.1:8000/index 原桌面 http://127.0.0.1:8000/hello/fsh hello,fsh&#xff08;index中hello方法&#x…...

商家必读!超店有数分享,tiktok达人营销变现如何更快一步?

近几年来&#xff0c;“粉丝经济”发展越来越迅猛&#xff0c;“网红带货”已经成为了一种营销的方式。这种方式让商家能基于达人的影响下迅速抢占自己的私域流量池。消费者会基于对达人的信任&#xff0c;购买达人推荐的产品。达人效应可以助力品牌走出营销困境。如果商家想要…...

操作系统(day11)--快表,两级页表

具有快表的地址变换机构 时间局限性&#xff1a;会有大量连续的指令需要访问同一个内存块的数据的情况&#xff08;程序中的循环&#xff09; 空间局限性&#xff1a;一旦程序访问了某个存储单元&#xff0c;在不久之后&#xff0c;其附近的存储单元也很有可能被访问。&#xf…...

预告| 亮点抢先看!第四届OpenI/O启智开发者大会主论坛24日启幕!

2023年2月24日至25日&#xff0c;第四届OpenI/O启智开发者大会将在深圳隆重举行。“算网筑基、开源启智、AI赋能”作为今年大会的主题&#xff0c;吸引了全球业界关注的目光。大会集结中国算力网资源基座、开源社区治理及AI开源生态建设、国家级开放创新应用平台、NLP大模型等前…...

猪齿鱼(Choerodon UI )的通用提交的封装 —— 两种方案,A.使用dataSet的自身的submit,B.使用axios.post来提交

submit组件&#xff08;otherSubmit/axiosSubmit&#xff09; 一、背景与简介 1、首先我们申请表提交&#xff0c;分为【保存】提交与【其他】提交&#xff1b; 1.1【保存】提交&#xff0c;要求表单必须要有变更&#xff0c;DataToJSON默认为dirty&#xff08;只转换变更的…...

CISCN(Web Ezpentest)GC、序列化、case when

目录 REGEXP的一个点&#xff08;正则&#xff09; like&#xff08;默认不区分大小写&#xff09; 当禁用了空格 regexp&#xff0c;like的区分大小写的使用方法 [CISCN 2022 初赛]ezpentest 卡点 2022 HFCTF babysql 最近又学到了一道新知识&#xff0c;case when的错…...

OSG三维渲染引擎编程学习之五十七:“第六章:OSG场景工作机制” 之 “6.1 OSG访问器”

目录 第六章 OSG场景工作机制 6.1 OSG访问器 6.1.1 访问器模式 6.1.2 osg::NodeVisitor 6.1.3 访问器示例...

Python3 输入和输出实例及演示

在前面几个章节中&#xff0c;我们其实已经接触了 Python 的输入输出的功能。本章节我们将具体介绍 Python 的输入输出。 输出格式美化 Python两种输出值的方式: 表达式语句和 print() 函数。 第3种方式是使用文件对象的 write() 方法&#xff0c;标准输出文件可以用 sys.std…...

召回-回忆录(持续更新)

0.召回方法 词召回 swing、itemCF 缺点&#xff1a; 有冷启动问题不是全局召回&#xff0c;冷门活动难以得到召回结果容易召回过多的头部热门活动 向量召回 参考文献&#xff1a; 经典推荐算法学习&#xff08;七&#xff09;| Graph Embedding技术学习 | 从DeepWalk到No…...

1243. 糖果/状态压缩dp【AcWing】

1243. 糖果 糖果店的老板一共有 M种口味的糖果出售。 为了方便描述&#xff0c;我们将 M种口味编号 1∼M。 小明希望能品尝到所有口味的糖果。 遗憾的是老板并不单独出售糖果&#xff0c;而是 K颗一包整包出售。 幸好糖果包装上注明了其中 K颗糖果的口味&#xff0c;所以小…...

【Spring Cloud Alibaba】001-单体架构与微服务架构

【Spring Cloud Alibaba】001-单体架构与微服务 文章目录【Spring Cloud Alibaba】001-单体架构与微服务一、单体架构1、单体应用与单体架构2、单体应用架构图3、单体架构优缺点优点缺点二、微服务1、微服务的“定义”2、微服务的特性3、微服务架构图4、微服务的优缺点优点缺点…...

Renderer 使用材质分析:materials、sharedMaterials 及 MaterialPropertyBlock

一、materials 与 sharedMaterials 1.1 使用上的区别与差异 Unity 开发时&#xff0c;在 C# 中通过 Renderer 取材质操作是非常常见的操作&#xff0c;Renderer 有两种常规获取材质的方式&#xff1a; sharedMaterials&#xff1a;可以理解这个就是原始材质&#xff0c;所有使…...

java学习----网络编程

网络编程入门 网络编程概述 计算机网络 ​ 计算机网络是指地理位置不同的具有独立功能的计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络操作系统&#xff0c;网络管理软件及网络通信协议的管理协调下&#xff0c;实现资源共享和信息传递的计算机系统…...

这些「误区」99%的研发都踩过

意识不到误区的存在最为离谱&#xff1b; 01生活中&#xff0c;职场上&#xff0c;游戏里&#xff0c;都少不了正面对喷过&#xff1a;意识太差&#xff1b; 在个人的认知中意识即思维&#xff0c;意识太差即思维中存在的误区比较多&#xff1b; 每个人或多或少都存在思维上的…...

Bi系统跟数据中台的区别是什么?

随着数据时代的发展&#xff0c;BI分析是当今数据时代必不可少的能力之一。BI系统通过系统化产品化的方法&#xff0c;能够大幅降低数据的获取成本、提升数据使用效率。同时借助可视化、交互式的操作&#xff0c;可以高效支持业务的分析及发展。 BI如此火热&#xff0c;随之而…...

微信小程序反编译方法分享

文章目录一、前言二、准备工作&#xff08;一&#xff09;安装Nodejs&#xff08;二&#xff09;解密和逆向工具三、小程序缓存文件解密&#xff08;一&#xff09;定位小程序缓存路径&#xff08;二&#xff09;源码解密&#xff08;三&#xff09;源码反编译四、小结一、前言…...

有了这些接口测试用例+工具,测试效率想不提升都难

写在前面&#xff1a;在日常开发过程中&#xff0c;有人做前端开发&#xff0c;有人负责后端开发。接口的主要作用就是连接前后台。但是&#xff0c;由于前端和后端开发的速度可能不一样&#xff0c;尤其是后端开发好了&#xff0c;但前端还未开发。这种时候我们需要做接口测试…...

麒麟 arm架构安装nginx

目录 1、下载nginx安装包并解压 在线安装&#xff1a; 离线安装&#xff1a; 上传nginx安装包&#xff08;下载地址&#xff1a;https://nginx.org/download/nginx-1.20.2.tar.gz&#xff09;到指定目录 2、安装系统相关依赖软件、组件包 1、上传或者下载对应的组件包 2、安…...

logrotate失效的排查---selinux开启状态拦截问题及解决方法

首先测试环境selinux 处于关闭状态 disable # getenforce disable重新开启selinux配置与生产环境一致 [rootlocal]# cat /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX can take one of these three values: # enforcing - S…...

Allegro使用总结-查看Layout基本操作:

好久没用CSDN写过笔记了&#xff0c;没想到无意间打开&#xff0c;编辑器更新啦&#xff01;以前巨难用的“富文本编辑器”终于改观了&#x1f62d;变的好像语雀&#xff0c;うれしい1. 视图/画面操作a. 画面缩放&#xff08;Zoom&#xff09;&#xff1a;F11/F12 或 鼠标滚轮b…...

cmd del命令笔记

使用 /s 删除文件夹下所有的 del /s sub # 删除目录下所有文件&#xff0c;这个目录不会删除 /p 确认提示 /q 静默模式&#xff0c;不会提示要不要删除 如过和/p同时使用&#xff0c;那么不提示 /a 根据属性删除&#xff0c;a是attribute的意思 del /a:r 01.jpg # 01.jp…...

apifox持续集成+java+企微机器人+xxljob定时推送

总览&#xff1a; apifox做接口测试后&#xff0c;把用例合并组装成测试套件&#xff0c;然后apifox-cli通过终端命令实现把套件执行后&#xff0c;输出本地文件的测试报告html或json。本地解析后拿到有用的解决通过定时执行推送到企微群里。 然后把html一起推到群里。 这个…...

盘点Linux内核网络知识100道题,这篇就够了

计算机网络模型 1、五层因特网协议栈和七层OSI&#xff08;Open System Interconnections&#xff09;参考模型分别是什么&#xff1f; 5层&#xff1a;应用层、传输层、网络层、数据链路层、物理层 7层&#xff1a;应用层、表示层、会话层、传输层、网络层、数据链路层、物理…...

专门做纪录片的网站/电脑优化软件哪个好用

ASM全称为Automated Storage Management&#xff0c;即自动存储管理&#xff0c;它是自Oracle10g这个版本Oracle推出的新功能。这是Oracle提供的一个卷管理器&#xff0c;用于替代操作操作系统所提供的LVM&#xff0c;它不仅支持单实例配置&#xff0c;也支持RAC这样的多实例配…...

南昌网站建设讯息/2021百度热搜年度榜

为了评估模型拟合的好坏&#xff0c;通常用损失函数&#xff08;觉得严格来说相当于下面的目标函数&#xff09;来度量拟合的程度。损失函数极小化&#xff0c;意味着拟合程度最好&#xff0c;对应的模型参数即为最优参数。 每一个算法都有一个目标函数&#xff08;objective f…...

wordpress商品导出淘宝/学历提升

各位Gopher们&#xff0c;因疫情影响&#xff0c;北京不允许举办大型线下活动&#xff0c;我们在征询过部分Gopher的意见后&#xff0c;决定取消今年的线下大会。对此&#xff0c;我们感到非常遗憾&#xff01;但各位Gopher也别太过伤心和惋惜&#xff0c;好事多磨&#xff0c;…...

tp5做企业网站/文明seo

涉及平台&#xff1a;平台管理&#xff08;包含自营店面&#xff09;、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;PC端、H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 核心架构&#xf…...

陕西省住房和城乡建设厅官网查询/域名seo站长工具

探究SpringBoot实现原理 注意&#xff1a; 难度较大&#xff0c;本版块作为选学内容&#xff0c;在开始前&#xff0c;必须完成SSM阶段源码解析部分的学习。 但是博主本人之前只了解过一点SSM知识&#xff0c;打算后面再补相关知识。 我们在前面的学习中切实感受到了SpringB…...

做网站采集内容/杭州网站seo外包

#!/bin/bash echo "wxc_dump.sh is running!" #抓包600秒保存一个包以时间命名 tcpdump -i ens160 -s0 -G 600 -Z root -w ./%Y%m%d_%H%M%S.pcap & #while条件括号里面不能少两个空格 #find当前路径所有后缀.pcap&#xff0c;文件内容最后修改时间比当前大于120分…...