赞
踩
目录
1. Oauth2 对外暴露的重要端口(REST API接口)
2) 校验token接口 /oauth/check_token
2. 创建Oauth2 Server 工程并注册到Nacos
服务名称 | 说明 |
nacos-server | 服务注册中心,提供服务发现与注册功能。 |
springcloud-gateway | 提供网关服务,网关尽量不做鉴权相关的操作,主要将请求路由到各微服务,实现统一转发请求到授权服务器 |
oauth2-project | 提供授权服务,通过客户端认证模式,将所有从网关转发过来的请求进行认证和授权。 |
user-service | 用户服务,普通微服务,同时也是资源服务器,需要配置鉴权转发。 |
名称 | 组 | 版本 | 说明 |
Java version | 11 | 为了支持springboot最新版本,使用java 11 | |
spring-boot-starter-parent | org.springframework.boot | 2.6.3 | Spring boot 版本 |
spring-cloud-dependencies | org.springframework.cloud | 2021.0.1 | Spring Cloud 版本 |
spring-cloud-alibaba-dependencies | com.alibaba.cloud | 2021.0.1.0 | Spring Cloud Alibaba 版本 |
spring-cloud-starter-gateway | org.springframework.cloud | 3.1.1 | Gateway 版本 |
spring-cloud-starter-alibaba-nacos-discovery | com.alibaba.cloud | 2021.0.1.0 | Nacos服务发现版本 |
spring-cloud-loadbalancer | org.springframework.cloud | 3.1.1 | 新版本gateway默认不支持 lb转发,因此需要添加此依赖支持与nacos转发的负载均衡 |
spring-cloud-starter-oauth2 | org.springframework.cloud | 2.2.4.RELEASE | oauth2 安全框架 |
nacos-server | 2.0.4 | naocs 注册中心 | |
mysql-connector-java | mysql | 5.1.46 | 提供mysql驱动和数据源 |
mybatis-spring-boot-starter | org.mybatis.spring.boot | 2.1.4 | 提供mybatis支持 |
mybatis-plus-boot-starter | com.baomidou | 3.2.0 | 提供mybatis-plus支持 |
spring-boot-starter-data-redis | org.springframework.boot | 2.6.3 | 提供redis支持 |
oauth2 是一个能由开发者定制的安全框架,我们可以借助oauth2来完成系统应用的授权和认证,从而达到保护应用安全的目的。
oauth2 框架中自了几个重要的API,我们用它前一定要熟悉以下的接口。
/oauth/token接口在org.springframework.security.oauth2.provider.endpoint里的TokenEndpoint类里, 该接口会以post请求方式对外提供以表单形式的认证方式,通过了就会返回带期限的token。
通过表单的形式提交, 通过后会返回一个带期限的access_token, 如下用客户端模式去申请token:
/oauth/check_token接口在org.springframework.security.oauth2.provider.endpoint包里的CheckTokenEndpoint类里,请求方式get和post都可以,可以看到需要一个token参数
校验成功后会返回客户端信息:
/oauth/authorize接口在org.springframework.security.oauth2.provider.endpoint包里的AuthorizationEndpoint, 该接口可用于授权模式的授权操作, 也可用于简化模式的直接申请token。
授权服务器: 给具有权限的资源拥有者对应的访问请求授权。
资源服务器: 受保护的资源,可以为静态资源、接口等。
资源拥有者: 具有该系统资源的拥有者,最终受益于用户。
客户端: 与用户和资源、授权服务器沟通的平台,如一个web应用客户端,QQ、微信以第三方形式登录的客户端。
理解了Oauth2的概念后,我们把注册中心、授权服务器、网关搭起来。
可以参考以下文章启动nacos-server
Nacos源码系列(一) 源码编译_Dream_it_possible!的博客-CSDN博客_nacos 源码编译
oauth2 认证client-id,client-secret,grant_type等信息需要的数据库表。
- /*
- Navicat Premium Data Transfer
-
- Source Server : win-local
- Source Server Type : MySQL
- Source Server Version : 50737
- Source Host : localhost:3306
- Source Schema : oauth2
-
- Target Server Type : MySQL
- Target Server Version : 50737
- File Encoding : 65001
-
- */
-
- SET NAMES utf8mb4;
- SET FOREIGN_KEY_CHECKS = 0;
-
- -- ----------------------------
- -- Table structure for oauth_client_details
- -- ----------------------------
- DROP TABLE IF EXISTS `oauth_client_details`;
- CREATE TABLE `oauth_client_details` (
- `client_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '客户端ID',
- `resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '资源ID集合,多个资源时用英文逗号分隔',
- `client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户端密匙',
- `scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户端申请的权限范围',
- `authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户端支持的grant_type',
- `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '重定向URI',
- `authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户端所拥有的SpringSecurity的权限值,多个用英文逗号分隔',
- `access_token_validity` int(11) NULL DEFAULT NULL COMMENT '访问令牌有效时间值(单位秒)',
- `refresh_token_validity` int(11) NULL DEFAULT NULL COMMENT '更新令牌有效时间值(单位秒)',
- `additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '预留字段',
- `autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户是否自动Approval操作',
- PRIMARY KEY (`client_id`) USING BTREE
- ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '客户端信息' ROW_FORMAT = Dynamic;
-
- -- ----------------------------
- -- Records of oauth_client_details
- -- ----------------------------
- INSERT INTO `oauth_client_details` VALUES ('client-app', NULL, '$2a$10$ABFuX9AEpqlGdgJfTrevb.J.5oAx18R7nKOENj13EBtGrYEvkrUoa', 'all', 'password,refresh_token,client_credentials,authorization_code,implicit', 'http://127.0.0.1:9010/dashboard', NULL, 3600, 604800, NULL, '1');
-
- SET FOREIGN_KEY_CHECKS = 1;
该表是存放客户端token 信息的表, 生成token时落库,验证时从该表里取出验证。
- /*
- Navicat Premium Data Transfer
-
- Source Server : win-local
- Source Server Type : MySQL
- Source Server Version : 50737
- Source Host : localhost:3306
- Source Schema : oauth2
-
- Target Server Type : MySQL
- Target Server Version : 50737
- File Encoding : 65001
-
- */
-
- SET NAMES utf8mb4;
- SET FOREIGN_KEY_CHECKS = 0;
-
- -- ----------------------------
- -- Table structure for oauth_access_token
- -- ----------------------------
- 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 COMMENT 'MD5加密的access_token的值',
- `token` blob NULL COMMENT 'OAuth2AccessToken.java对象序列化后的二进制数据',
- `authentication_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'MD5加密过的username,client_id,scope',
- `user_name` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '登录的用户名',
- `client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '客户端ID',
- `authentication` blob NULL COMMENT 'OAuth2Authentication.java对象序列化后的二进制数据',
- `refresh_token` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'MD5加密后的refresh_token的值',
- PRIMARY KEY (`authentication_id`) USING BTREE
- ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '访问令牌' ROW_FORMAT = Dynamic;
-
- -- ----------------------------
- -- Records of oauth_access_token
- -- ----------------------------
- INSERT INTO `oauth_access_token` VALUES ('cfd26bb25194ad1ae6fe1a2b759c7ba6', 0xACED0005737200436F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744F4175746832416363657373546F6B656E0CB29E361B24FACE0200064C00156164646974696F6E616C496E666F726D6174696F6E74000F4C6A6176612F7574696C2F4D61703B4C000A65787069726174696F6E7400104C6A6176612F7574696C2F446174653B4C000C72656672657368546F6B656E74003F4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F636F6D6D6F6E2F4F417574683252656672657368546F6B656E3B4C000573636F706574000F4C6A6176612F7574696C2F5365743B4C0009746F6B656E547970657400124C6A6176612F6C616E672F537472696E673B4C000576616C756571007E000578707372001E6A6176612E7574696C2E436F6C6C656374696F6E7324456D7074794D6170593614855ADCE7D002000078707372000E6A6176612E7574696C2E44617465686A81014B597419030000787077080000018079CB3BD3787372004C6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744578706972696E674F417574683252656672657368546F6B656E2FDF47639DD0C9B70200014C000A65787069726174696F6E71007E0002787200446F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744F417574683252656672657368546F6B656E73E10E0A6354D45E0200014C000576616C756571007E0005787074002431643465383931652D343737362D346138362D623966372D6330643132623732376430347371007E00097708000001809DA0D15278737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65536574801D92D18F9B80550200007872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C0001637400164C6A6176612F7574696C2F436F6C6C656374696F6E3B7870737200176A6176612E7574696C2E4C696E6B656448617368536574D86CD75A95DD2A1E020000787200116A6176612E7574696C2E48617368536574BA44859596B8B7340300007870770C000000103F40000000000001740003616C6C7874000662656172657274002430393934333030612D633966632D346233382D393732392D383761663261326562366462, '702834532a7bab38cab035bd2e8c3fee', NULL, 'client-app', 0xACED0005737200416F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F417574683241757468656E7469636174696F6EBD400B02166252130200024C000D73746F7265645265717565737474003C4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F4F4175746832526571756573743B4C00127573657241757468656E7469636174696F6E7400324C6F72672F737072696E676672616D65776F726B2F73656375726974792F636F72652F41757468656E7469636174696F6E3B787200476F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E416273747261637441757468656E7469636174696F6E546F6B656ED3AA287E6E47640E0200035A000D61757468656E746963617465644C000B617574686F7269746965737400164C6A6176612F7574696C2F436F6C6C656374696F6E3B4C000764657461696C737400124C6A6176612F6C616E672F4F626A6563743B787000737200266A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654C697374FC0F2531B5EC8E100200014C00046C6973747400104C6A6176612F7574696C2F4C6973743B7872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C00016371007E00047870737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A657870000000007704000000007871007E000C707372003A6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F41757468325265717565737400000000000000010200075A0008617070726F7665644C000B617574686F72697469657371007E00044C000A657874656E73696F6E7374000F4C6A6176612F7574696C2F4D61703B4C000B72656469726563745572697400124C6A6176612F6C616E672F537472696E673B4C00077265667265736874003B4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F546F6B656E526571756573743B4C000B7265736F7572636549647374000F4C6A6176612F7574696C2F5365743B4C000D726573706F6E7365547970657371007E0011787200386F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E426173655265717565737436287A3EA37169BD0200034C0008636C69656E74496471007E000F4C001172657175657374506172616D657465727371007E000E4C000573636F706571007E0011787074000A636C69656E742D617070737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654D6170F1A5A8FE74F507420200014C00016D71007E000E7870737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F400000000000037708000000040000000274000A6772616E745F74797065740012636C69656E745F63726564656E7469616C73740009636C69656E745F696474000A636C69656E742D61707078737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65536574801D92D18F9B80550200007871007E0009737200176A6176612E7574696C2E4C696E6B656448617368536574D86CD75A95DD2A1E020000787200116A6176612E7574696C2E48617368536574BA44859596B8B7340300007870770C000000103F40000000000001740003616C6C78017371007E0020770C000000103F40000000000000787371007E00173F40000000000000770800000010000000007870707371007E0020770C000000103F40000000000000787371007E0020770C000000103F400000000000007870, '1bcc81c9038d7305e2ca339a9a3732db');
-
- SET FOREIGN_KEY_CHECKS = 1;
刷新token的记录表, token_id字段与oauth_access_token的refresh_token字段关联。
- /*
- Navicat Premium Data Transfer
-
- Source Server : win-local
- Source Server Type : MySQL
- Source Server Version : 50737
- Source Host : localhost:3306
- Source Schema : oauth2
-
- Target Server Type : MySQL
- Target Server Version : 50737
- File Encoding : 65001
-
- */
-
- SET NAMES utf8mb4;
- SET FOREIGN_KEY_CHECKS = 0;
-
- -- ----------------------------
- -- Table structure for oauth_refresh_token
- -- ----------------------------
- 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 COMMENT 'MD5加密过的refresh_token的值',
- `token` blob NULL COMMENT 'OAuth2RefreshToken.java对象序列化后的二进制数据',
- `authentication` blob NULL COMMENT 'OAuth2Authentication.java对象序列化后的二进制数据'
- ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '更新令牌' ROW_FORMAT = Dynamic;
-
- -- ----------------------------
- -- Records of oauth_refresh_token
- -- ----------------------------
- INSERT INTO `oauth_refresh_token` VALUES ('1bcc81c9038d7305e2ca339a9a3732db', 0xACED00057372004C6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744578706972696E674F417574683252656672657368546F6B656E2FDF47639DD0C9B70200014C000A65787069726174696F6E7400104C6A6176612F7574696C2F446174653B787200446F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744F417574683252656672657368546F6B656E73E10E0A6354D45E0200014C000576616C75657400124C6A6176612F6C616E672F537472696E673B787074002431643465383931652D343737362D346138362D623966372D6330643132623732376430347372000E6A6176612E7574696C2E44617465686A81014B59741903000078707708000001809DA0D15278, 0xACED0005737200416F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F417574683241757468656E7469636174696F6EBD400B02166252130200024C000D73746F7265645265717565737474003C4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F4F4175746832526571756573743B4C00127573657241757468656E7469636174696F6E7400324C6F72672F737072696E676672616D65776F726B2F73656375726974792F636F72652F41757468656E7469636174696F6E3B787200476F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E416273747261637441757468656E7469636174696F6E546F6B656ED3AA287E6E47640E0200035A000D61757468656E746963617465644C000B617574686F7269746965737400164C6A6176612F7574696C2F436F6C6C656374696F6E3B4C000764657461696C737400124C6A6176612F6C616E672F4F626A6563743B787000737200266A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654C697374FC0F2531B5EC8E100200014C00046C6973747400104C6A6176612F7574696C2F4C6973743B7872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C00016371007E00047870737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A657870000000007704000000007871007E000C707372003A6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F41757468325265717565737400000000000000010200075A0008617070726F7665644C000B617574686F72697469657371007E00044C000A657874656E73696F6E7374000F4C6A6176612F7574696C2F4D61703B4C000B72656469726563745572697400124C6A6176612F6C616E672F537472696E673B4C00077265667265736874003B4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F546F6B656E526571756573743B4C000B7265736F7572636549647374000F4C6A6176612F7574696C2F5365743B4C000D726573706F6E7365547970657371007E0011787200386F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E426173655265717565737436287A3EA37169BD0200034C0008636C69656E74496471007E000F4C001172657175657374506172616D657465727371007E000E4C000573636F706571007E0011787074000A636C69656E742D617070737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654D6170F1A5A8FE74F507420200014C00016D71007E000E7870737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F400000000000037708000000040000000274000A6772616E745F74797065740012636C69656E745F63726564656E7469616C73740009636C69656E745F696474000A636C69656E742D61707078737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65536574801D92D18F9B80550200007871007E0009737200176A6176612E7574696C2E4C696E6B656448617368536574D86CD75A95DD2A1E020000787200116A6176612E7574696C2E48617368536574BA44859596B8B7340300007870770C000000103F40000000000001740003616C6C78017371007E0020770C000000103F40000000000000787371007E00173F40000000000000770800000010000000007870707371007E0020770C000000103F40000000000000787371007E0020770C000000103F400000000000007870);
- INSERT INTO `oauth_refresh_token` VALUES ('4c64de4ee4fe5845c6b793c58f39292b', 0xACED00057372004C6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744578706972696E674F417574683252656672657368546F6B656E2FDF47639DD0C9B70200014C000A65787069726174696F6E7400104C6A6176612F7574696C2F446174653B787200446F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E636F6D6D6F6E2E44656661756C744F417574683252656672657368546F6B656E73E10E0A6354D45E0200014C000576616C75657400124C6A6176612F6C616E672F537472696E673B787074002464333337666233332D366462642D343563332D623138372D3265303164623539323065307372000E6A6176612E7574696C2E44617465686A81014B59741903000078707708000001809DC0526778, 0xACED0005737200416F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F417574683241757468656E7469636174696F6EBD400B02166252130200024C000D73746F7265645265717565737474003C4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F4F4175746832526571756573743B4C00127573657241757468656E7469636174696F6E7400324C6F72672F737072696E676672616D65776F726B2F73656375726974792F636F72652F41757468656E7469636174696F6E3B787200476F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E416273747261637441757468656E7469636174696F6E546F6B656ED3AA287E6E47640E0200035A000D61757468656E746963617465644C000B617574686F7269746965737400164C6A6176612F7574696C2F436F6C6C656374696F6E3B4C000764657461696C737400124C6A6176612F6C616E672F4F626A6563743B787000737200266A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654C697374FC0F2531B5EC8E100200014C00046C6973747400104C6A6176612F7574696C2F4C6973743B7872002C6A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65436F6C6C656374696F6E19420080CB5EF71E0200014C00016371007E00047870737200136A6176612E7574696C2E41727261794C6973747881D21D99C7619D03000149000473697A657870000000007704000000007871007E000C707372003A6F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E4F41757468325265717565737400000000000000010200075A0008617070726F7665644C000B617574686F72697469657371007E00044C000A657874656E73696F6E7374000F4C6A6176612F7574696C2F4D61703B4C000B72656469726563745572697400124C6A6176612F6C616E672F537472696E673B4C00077265667265736874003B4C6F72672F737072696E676672616D65776F726B2F73656375726974792F6F61757468322F70726F76696465722F546F6B656E526571756573743B4C000B7265736F7572636549647374000F4C6A6176612F7574696C2F5365743B4C000D726573706F6E7365547970657371007E0011787200386F72672E737072696E676672616D65776F726B2E73656375726974792E6F61757468322E70726F76696465722E426173655265717565737436287A3EA37169BD0200034C0008636C69656E74496471007E000F4C001172657175657374506172616D657465727371007E000E4C000573636F706571007E0011787074000A636C69656E742D617070737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C654D6170F1A5A8FE74F507420200014C00016D71007E000E7870737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F400000000000067708000000080000000374000A6772616E745F7479706574000870617373776F7264740009636C69656E745F696474000A636C69656E742D617070740008757365726E616D6574000462696E6778737200256A6176612E7574696C2E436F6C6C656374696F6E7324556E6D6F6469666961626C65536574801D92D18F9B80550200007871007E0009737200176A6176612E7574696C2E4C696E6B656448617368536574D86CD75A95DD2A1E020000787200116A6176612E7574696C2E48617368536574BA44859596B8B7340300007870770C000000103F40000000000001740003616C6C78017371007E0022770C000000103F40000000000000787371007E00173F40000000000000770800000010000000007870707371007E0022770C000000103F40000000000000787371007E0022770C000000103F40000000000000787372004F6F72672E737072696E676672616D65776F726B2E73656375726974792E61757468656E7469636174696F6E2E557365726E616D6550617373776F726441757468656E7469636174696F6E546F6B656E00000000000002300200024C000B63726564656E7469616C7371007E00054C00097072696E636970616C71007E00057871007E0003017371007E00077371007E000B000000007704000000007871007E002C737200176A6176612E7574696C2E4C696E6B6564486173684D617034C04E5C106CC0FB0200015A000B6163636573734F726465727871007E00173F400000000000067708000000080000000474000D636C69656E745F73656372657474001161736466686F6C7531326A6F736164662371007E001971007E001A71007E001B71007E001C71007E001D71007E001E780070737200326F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E7573657264657461696C732E5573657200000000000002300200075A00116163636F756E744E6F6E457870697265645A00106163636F756E744E6F6E4C6F636B65645A001563726564656E7469616C734E6F6E457870697265645A0007656E61626C65644C000B617574686F72697469657371007E00114C000870617373776F726471007E000F4C0008757365726E616D6571007E000F7870010101017371007E001F737200116A6176612E7574696C2E54726565536574DD98509395ED875B0300007870737200466F72672E737072696E676672616D65776F726B2E73656375726974792E636F72652E7573657264657461696C732E5573657224417574686F72697479436F6D70617261746F7200000000000002300200007870770400000000787071007E001E);
-
- SET FOREIGN_KEY_CHECKS = 1;
系统用户表, 主要包含用户信息,密码采用BCryptPasswordEncoder加密方法encode后的结果。
- /*
- Navicat Premium Data Transfer
-
- Source Server : win-local
- Source Server Type : MySQL
- Source Server Version : 50737
- Source Host : localhost:3306
- Source Schema : oauth2
-
- Target Server Type : MySQL
- Target Server Version : 50737
- File Encoding : 65001
-
- */
-
- SET NAMES utf8mb4;
- SET FOREIGN_KEY_CHECKS = 0;
-
- -- ----------------------------
- -- Table structure for sys_user
- -- ----------------------------
- DROP TABLE IF EXISTS `sys_user`;
- CREATE TABLE `sys_user` (
- `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
- `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `pass_word` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `nick_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `sex` int(2) NULL DEFAULT NULL,
- `phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `enable` int(2) NULL DEFAULT NULL,
- `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `create_time` datetime(0) NULL DEFAULT NULL,
- `account_expired` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '账号是否失效',
- `account_locked` tinyint(1) UNSIGNED NULL DEFAULT 0 COMMENT '账号是否被锁定',
- PRIMARY KEY (`id`) USING BTREE,
- UNIQUE INDEX `user_name`(`user_name`) USING BTREE
- ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-
- -- ----------------------------
- -- Records of sys_user
- -- ----------------------------
- INSERT INTO `sys_user` VALUES (1, 'admin', '$2a$10$gHF4b6c.Z4LrSqly3kpLwegXzBo6Q1TtBQlcrXt6Lctu/aLAZlPQe', 'bingbing', 1, '123', 1, '123456@qq.com', '', '2022-04-28 11:02:15', 0, 0);
- INSERT INTO `sys_user` VALUES (2, 'bing', '$2a$10$FgJjpqW0WihRn/aYXxh8QuO0vp2iGK268H/G8VmbF5kRXeK5b23UG', 'bing', 1, '131', 1, '', '', '2022-04-28 18:25:32', 0, 0);
- INSERT INTO `sys_user` VALUES (3, 'test01', '4b15d2b3b671209e01202331881af5a6044d342dc624d29a53ed6b4402af6d61', 'test', 1, '2312', 1, '1212', NULL, NULL, 0, 0);
-
- SET FOREIGN_KEY_CHECKS = 1;
核心依赖: spring-cloud-starter-oauth2, 版本尽量选择较新的。
- <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>com.bing.cloud</groupId>
- <artifactId>oauth2-project</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </parent>
- <artifactId>oauth2-server</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>oauth2-server</name>
- <description>Demo project for Spring Boot</description>
-
- <properties>
- <java.version>11</java.version>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-jdbc</artifactId>
- </dependency>
-
-
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-actuator</artifactId>
- </dependency>
-
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.46</version>
- </dependency>
-
- <!-- redis-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
-
- <!--整合mybatis-->
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>2.1.4</version>
- </dependency>
-
- <!-- mybatis-plus插件-->
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- <version>3.2.0</version>
- </dependency>
-
-
-
- <!--集成druid连接池-->
- <dependency>
-
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- <version>1.1.10</version>
-
- </dependency>
-
-
-
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
- </dependency>
- <!--security -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-oauth2</artifactId>
- <version>2.2.4.RELEASE</version>
- </dependency>
-
-
-
-
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </dependency>
-
-
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
-
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>${java.version}</source>
- <target>${java.version}</target>
- </configuration>
- </plugin>
-
- </plugins>
- </build>
-
-
- </project>
配置mysql数据源、nacos 注册中心、redis、mybatis, 注意配置spring.application.name, spring.application.name作为微服务名字注册到nacos里。
- server:
- port: 9010
- servlet:
- context-path: /
- spring:
- application:
- name: oauth2-server-service
- datasource:
- driver-class-name: com.mysql.jdbc.Driver
- url: jdbc:mysql://localhost:3306/oauth2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
- username: root
- password: root
- cloud:
- nacos:
- discovery:
- server-addr: localhost:8848
- username: nacos
- password: nacos
- redis:
- host: localhost
- port: 6379
- password: redis#847652.
- database: 0
- management:
- endpoints:
- web:
- exposure:
- include: "*"
-
- #mybatis
- mybatis:
- mapper-locations:
- - classpath:mapper/*.xml
- - classpath:com/**/mapper/*.xml
- # myabtis-domain
- mybatis-plus:
- type-aliases-package: com.bing.cloud.**.entity
- package com.bing.cloud.config;
-
- import com.bing.cloud.service.impl.CustomUserDetailServiceImpl;
- import lombok.AllArgsConstructor;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.security.authentication.AuthenticationManager;
- 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.store.JdbcTokenStore;
- import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
-
-
- import javax.sql.DataSource;
-
-
- /**
- * 认证服务器配置
- */
- @AllArgsConstructor
- @Configuration
- @EnableAuthorizationServer
- public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
-
- private final CustomUserDetailServiceImpl userDetailsService;
- private final AuthenticationManager authenticationManager;
-
- // private final PasswordEncoder passwordEncoder;
-
-
- @Autowired
- private DataSource dataSource;
-
- @Autowired
- private RedisConnectionFactory redisConnectionFactory;
-
-
- /**
- * 基于数据库认证
- *
- * @return
- */
- @Bean
- public ClientDetailsService customClientDetailsService() {
- return new JdbcClientDetailsService(dataSource);
- }
-
-
- /**
- * token 落库
- *
- * @return
- */
- public JdbcTokenStore jdbcTokenStore() {
- return new JdbcTokenStore(dataSource);
- }
-
- public RedisTokenStore redisTokenStore(){
- return new RedisTokenStore(redisConnectionFactory);
- }
-
- @Override
- public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
- clients.withClientDetails(customClientDetailsService());
- // 由于配置了JDBCClient, 因此会去查询数据库oauth_client_details,因此下面的配置可以不需要
- // .withClient("client-app")
- // .secret(passwordEncoder.encode("asdfholu12josadf#"))
- // .autoApprove(true)
- // .redirectUris("http://127.0.0.1:9010/dashboard")
- // .scopes("all")
- // .authorizedGrantTypes("password", "implicit", "client_credentials", "authorization_code","refresh_token")
- // .accessTokenValiditySeconds(3600)
- // .refreshTokenValiditySeconds(86400);
- }
-
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
- //配置加载用户信息的服务
- // token 落库
- endpoints.authenticationManager(authenticationManager)
- .userDetailsService(userDetailsService)
- .tokenStore(redisTokenStore())
- ;
- }
-
-
- /**
- * 解决访问/oauth/check_token 403的问题
- *
- * @param security
- * @throws Exception
- */
- @Override
- public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
- // 允许表单认证
- security
- .tokenKeyAccess("permitAll()")
- .checkTokenAccess("permitAll()")
- .allowFormAuthenticationForClients();
-
- }
-
-
- }
auth-server-service对外提供的api也可以看做资源,同样支持授权和认证。
- package com.bing.cloud.config;
-
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
- import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
-
- /**
- * 资源服务器配置
- */
- @Configuration
- @EnableResourceServer
- public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
-
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.authorizeRequests()
- .anyRequest()
- .authenticated()
- .and()
- .requestMatchers()
- .antMatchers("/api/**");//配置需要保护的资源路径
-
- }
- }
可以在WebSecurityConfigurerAdapter里configure方法里配置不需要拦截的url, 比如一些登录、登出地址, 默认登录页面用 .formLogin()。
- package com.bing.cloud.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.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.crypto.password.PasswordEncoder;
-
- /**
- * SpringSecurity配置
- */
- @Configuration
- @EnableWebSecurity
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
-
- @Bean
- public PasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
- }
-
- @Bean
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
- }
-
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.csrf()
- .disable()
- .httpBasic()
- .and()
- .authorizeRequests()
- // 配置可以直接访问的页面
- .antMatchers("/login/**", "/logout/**", "/api/getCurrentUser")
- .permitAll()
- // 其余所有请求都要通过认证鉴权
- .anyRequest()
- .authenticated()
- .and()
- // 配置spring security默认的登录页面
- .formLogin()
- .permitAll();
- }
- }
当使用密码模式请求/oauth/token接口时,我们可以使用自己创建的数据库与oauth2进行集成,只需要重写UserDetailService里的loadUserByUserName(String username)方法即可。
创建SecurityUser对象,使用mybatisplus插件映射到sys_user表。
- package com.bing.cloud.service.impl;
-
- import com.bing.cloud.MessageConstant;
- import com.bing.cloud.entity.SecurityUser;
- import com.bing.cloud.service.UserService;
- import com.google.gson.GsonBuilder;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.security.authentication.AccountExpiredException;
- import org.springframework.security.authentication.DisabledException;
- import org.springframework.security.authentication.LockedException;
- import org.springframework.security.core.authority.AuthorityUtils;
- import org.springframework.security.core.authority.SimpleGrantedAuthority;
- import org.springframework.security.core.userdetails.User;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.core.userdetails.UsernameNotFoundException;
- import org.springframework.security.crypto.password.PasswordEncoder;
- import org.springframework.stereotype.Service;
-
- import javax.annotation.PostConstruct;
- import java.util.ArrayList;
- import java.util.List;
-
-
- /**
- * 自定义用户服务
- */
- @Service
- public class CustomUserDetailServiceImpl implements UserDetailsService {
-
-
- @Autowired
- private UserService userService;
-
-
- @Override
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- // 基于数据库认证
- SecurityUser userInfo = userService.selectUserByUserName(username);
- if (!userInfo.isEnabled()) {
- throw new DisabledException(MessageConstant.ACCOUNT_DISABLED);
- } else if (userInfo.isAccountLocked()) {
- throw new LockedException(MessageConstant.ACCOUNT_LOCKED);
- } else if (userInfo.isAccountExpired()) {
- throw new AccountExpiredException(MessageConstant.ACCOUNT_EXPIRED);
- }
- // 获取到所有的role, 把role写入到simpleGrantedAuthority里。
- List<SimpleGrantedAuthority> authorities = new ArrayList<>();
- // String password = passwordEncoder.encode(userInfo.getPassword());
- return new User(username, userInfo.getPassword(), authorities);
-
- }
-
-
- }
如果需要配置一些role, 可以通过mybatis将role表里的角色添加到SimpleGrantedAuthority列表里。
上述操作如果无误后启动 Auth-Server,能在nacos 里发现注册成功即可。
如果还有不了解gateway的朋友,推荐抽点时间浏览一下以下的文章
微服务架构网关组件Spring Cloud Gateway 用法详解和实战案例_Dream_it_possible!的博客-CSDN博客
本节目标是创建一个网关服务,实现请求能通过nacos转发到auth-server服务器上。
网关的作用是为了统一请求的入口,因此不建议在网关里写入大量的鉴权逻辑,新建一个springboot工程
- <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.6.3</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <groupId>com.example.gateway</groupId>
- <artifactId>cloud-gateway</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>cloud-gateway</name>
- <description>project for Spring Boot</description>
- <properties>
- <java.version>11</java.version>
- <java.version>11</java.version>
- <docker.registry.url>116.62.146.90</docker.registry.url>
- <docker.namespace>my-shop</docker.namespace>
- <spring-cloud.version>2021.0.1</spring-cloud.version>
- <spring.cloud.alibaba.version>2021.0.1.0</spring.cloud.alibaba.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-gateway</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
- </dependency>
-
- <!--整合断路器-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
- <version>2.2.4.RELEASE</version>
- </dependency>
- <!-- 添加eureka客户端-->
- <!-- <dependency>-->
- <!-- <groupId>org.springframework.cloud</groupId>-->
- <!-- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>-->
- <!-- </dependency>-->
-
-
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
- </dependency>
-
-
-
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </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>
-
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-alibaba-dependencies</artifactId>
- <version>${spring.cloud.alibaba.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
-
- </dependencies>
- </dependencyManagement>
-
- <build>
- <finalName>my-gateway</finalName>
- <resources>
- <resource>
- <directory>src/main/java</directory>
- <includes>
- <include>**/*.xml</include>
- </includes>
- </resource>
- <resource>
- <directory>src/main/resources</directory>
- </resource>
- </resources>
-
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
-
- <plugin>
- <groupId>com.spotify</groupId>
- <artifactId>dockerfile-maven-plugin</artifactId>
- <version>1.4.13</version>
- <executions>
- <execution>
- <id>build_image</id>
- <phase>package</phase>
- <goals>
- <!--如果package时不想用docker打包,就注释掉这个goal -->
- <goal>build</goal>
- <goal>push</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <contextDirectory>${project.basedir}</contextDirectory>
- <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
- <repository>${docker.registry.url}/${docker.namespace}/${project.artifactId}</repository>
- <tag>${project.version}</tag>
- <buildArgs>
- <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
- </buildArgs>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- </project>
添加auth-service-routte路由,注意将uri设置为lb://oauth2-server-service,因为通过nacos转发时,会根据服务名进行负载均衡式的请求。
可以在predicates里配置StripPrefix=1, 转发到目标服务后会去掉Path里第一个"/"和第二个"/"里的内容。
- server:
- port: 9000
- spring:
- application:
- name: gateway
- cloud:
- gateway:
- discovery:
- locator:
- enabled: true
- lower-case-service-id: true
- routes:
- - id: user-service #路由的ID
- uri: lb://user-service
- predicates:
- - Method=GET,POST
- - Path=/user/**
- filters:
- - StripPrefix=1
- - name: Retry
- args:
- retires: 1
- statuses: BAD_GATEWAY
- - id: auth-service-route
- uri: lb://oauth2-server-service
- predicates:
- - Method=GET,POST
- - Path=/auth-server/**
- filters:
- - name: Retry
- args:
- retries: 1 # 调用失败需要进行重试的次数,比如因为网络原因出现502等
- statuses: BAD_GATEWAY
- - StripPrefix=1
-
- nacos:
- server-addr: localhost:8848
- discovery:
- server-addr: ${spring.cloud.nacos.server-addr}
- username: nacos
- password: nacos
- namespace: public
-
- logging:
- level:
- org.springframework.cloud.gateway: debug
启动网关服务, 可以从控制台看到我们配置的路由和相关的规则。
首先在auth-server添加一个测试api: /api/hello,使用postman访问请求localhost:9000/auth-server/api/hello。
解决用网关转发Lb时,一直报503的问题:
由于最新版spring cloud的gateway不支持负载均衡功能,因此需要手动添加一个loadbalancer依赖:
-
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-loadbalancer</artifactId>
- </dependency>
重新刷新依赖、启动网关微服务,访问localhost:9000/auth-server/api/hello,响应代码为: 401, 说明请求正确的转发到auth-server:
在一个大型的分布式系统里,存在的微服务可能有几十个或者上百个,如何使用网关和oauth server来保护,我们可以将普通微服务的未认证的请求全部由网关转发给鉴权服务器。
同样集成nacos, oauth2,mybatis 等框架,运行起来后能在nacos中发现。
放了方便配置资源服务器,我们将所有需要认证的接口都带上/api前缀。
- package com.bingbing.sh.config;
-
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
- import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
-
- /**
- * 资源服务器配置
- */
- @Configuration
- @EnableResourceServer
- public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
-
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.authorizeRequests()
- .anyRequest()
- .authenticated()
- .and()
- .requestMatchers()
- .antMatchers("/api/**");//配置需要保护的资源路径
-
- }
- }
需要注意client-id和client-secret要与数据库里保持一致,可以选择使用客户端模式的进行认证,另外ecurity.oauth2.resource.token-info-uri这个值配为:oauth2-server的/oauth/check_token。
在application.properties文件里添加以下配置:
- security.oauth2.client.access-token-uri=http://localhost:9000/auth-server/oauth/token
- security.oauth2.client.client-authentication-scheme=form
- security.oauth2.client.client-id=client-app
- security.oauth2.client.client-secret=asdfholu12josadf#
- security.oauth2.client.grant-type=client_credentials
- security.oauth2.resource.token-info-uri=http://localhost:9000/auth-server/oauth/check_token
接着进入到OAuth2AuthenticationManager.authenticate方法:
然后进入到tokenServices.loadAuthentication()方法:
默认进入到DefaultTokenService里的loadAuthentication:
可以发现默认是进入到DefaultTokenService认证token的,我们可以推断出肯定是不行的,因为我在user-service的项目里没有配置授权服务器,简单讲user-service是没有授权功能的。
接着我们把注释的配置放开,然后进入到loadAuthentication方法,发现是通过RemoteTokenServices调用的,向我们配置的security.oauth2.resource.token-info-uri 地址发起了一个rest请求:
如果token是正确的话,/oauth/check_token接口会返回一个map给我们
我们需要基于数据库的进行认证,那么需要在数据库里也配置所有的授权模式。
在authorized_grant_types字段里配置4种模式,用"," 隔开: password,client_credentials,authorization_code,implicit,在配置可以在加一个refresh_token,用于支持刷新token。
授权码模式是现在最严密、最安全的一种认证模式,第三方应用先通过登录获取到一个授权码和directUrl, 然后携带授权码和directUrl去授权服务器请求token令牌, 其中direct_url配置在数据库里,参数中的grant_type为client_credentials。
第一步在浏览器中访问如下地址:
http://localhost:9010/oauth/authorize?client_id=client-app&client_secret=asdfholu12josadf%23&response_type=code
输入用户名和密码:
登录成功后会在地址栏上返回一个code,每次申请的code只能使用一次, 由于我没有配置/dashboard页面,因此会报404的错误:
拿到code后,使用postman采用授权码模式请求token:
再次用同样的code去请求就会报错:Invalid authorization code: n2jZMX,必须重新访问/oauth/authorize重新申请一个新的code才行。
简化模式是直接在浏览器中向授权服务器申请令牌,成功了就能拿到token,参数中的grant_type为token。
第一步在浏览器中输入:
localhost:9010/oauth/authorize?grant_type=implicit&client_id=client-app&scope=all&redirect_uri=http://127.0.0.1:9010/dashboard&response_type=token
其中 redirect_uri和grant_type均配置在数据库里,如果没有登录,那么会先输入用户名和密码,登录成功后,会在地址栏上显示出token和失效时间。
密码模式是用户向客户端提供用户名和密码,客户端使用这些信息向授权服务器去申请令牌,参数中的grant_type为password,需要客户端应用与服务器提供商高度信息,必须是同一家公司。
密码模式直接将客户端ID、secret、用户名和密码放在body的表单里,用postman发一个post请求。
localhost:9010/oauth/token
body里的参数
grant_type:password
client_id:client-app
client_secret:asdfholu12josadf#
username:bing
password:123456
客户端模式是指客户端用自己的名义而不是用户的身份去向授权服务器申请令牌。
用postman请求localhost:9010/oauth/token, body里的参数为:
grant_type:client_credentials
client_id:client-app
client_secret:asdfholu12josadf#
以上就是搭建统一鉴权的所有流程,4种模式都可以使用,可根据不同的场景进行甄选。
参考:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。