SpringCloudAlibaba+Zuul+OAuth2 搭建认证微服务
Posted 1156184981651a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloudAlibaba+Zuul+OAuth2 搭建认证微服务相关的知识,希望对你有一定的参考价值。
开发背景什么的我就不介绍了官网介绍:https://spring.io/guides/tutorials/spring-boot-oauth2/ 既然大家需要用到这个技术 直接撸代码吧!!!
1.创建maven springboot项目 添加相关依赖 采用最新的版本(相关依赖版本如下)
<!--spring-boot 版本-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<!--spring-cloud spring cloud alibaba版本-->
<dependencyManagement>
<dependencies>
<!--整合spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</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.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!--整合oauth2-->
<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>
2.创建oauth2 认证服务器配置类
/**
*
* @Description Authorization配置
* @Date 2020/6/24 11:36
* @Author Jax
*/
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthServiceConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
/**
* 这里先把服务写到内存里面 后续配置到mysql
* 配置client服务详情(也就说有哪些服务可以来向我申请令牌)
* see:org.springframework.security.oauth2.provider.authentication
* 我这里假设我现在有一个游戏微服务game_client 一个网关微服务gateway_client
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("game_client")
.secret(passwordEncoder.encode("123456"))
.accessTokenValiditySeconds(3600)//token的失效时间 单位秒
.resourceIds("game-service")
.scopes("read", "write")//控制发出去的服务令牌权限
.authorizedGrantTypes("password")//授权方式
.and()
.withClient("gateway_client")
.secret(passwordEncoder.encode("123456"))
.accessTokenValiditySeconds(3600)
.resourceIds("gateway")
.scopes("read", "write")
.authorizedGrantTypes("password");
}
//OAuth2为我们提供了四种授权方式:
//1、授权码模式(authorization code)
//授权码相对其他三种来说是功能比较完整、流程最安全严谨的授权方式,通过客户端的后台服务器与服务提供商的认证服务器交互来完成
//2、简化模式(implicit)
//这种模式不通过服务器端程序来完成,直接由浏览器发送请求获取令牌,令牌是完全暴露在浏览器中的,这种模式极力不推崇
//3、密码模式(resource owner password credentials)
//密码模式也是比较常用到的一种,客户端向授权服务器提供用户名、密码然后得到授权令牌。这种模式不过有种弊端,我们的客户端需要存储用户输入的密码,但是对于用户来说信任度不高的平台是不可能让他们输入密码的
//4、客户端模式(client credentials)
//客户端模式是客户端以自己的名义去授权服务器申请授权令牌,并不是完全意义上的授权。
}
3.需要配置认证服务器知道可以让哪些用户来访问我 即authenticationManager配置
/**
*
* @Description Authorization配置
* @Date 2020/6/24 11:36
* @Author Jax
*/
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthServiceConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private PasswordEncoder passwordEncoder;
/**
* 这里先把服务写到内存里面 生产环境肯定是不行的 需要配置mysql参考我下面的配置
* 建议先把流程走通 再倒回来 配置mysql持久化
* 配置client服务详情(也就说有哪些服务可以来向我申请令牌)
* see:org.springframework.security.oauth2.provider.authentication
* 我这里假设我现在有一个游戏微服务game_client 一个网关微服务gateway_client
* @param clients
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("game_client")
.secret(passwordEncoder.encode("123456"))
.accessTokenValiditySeconds(3600)
.resourceIds("gateway", "game-service")
.scopes("read", "write")
.authorizedGrantTypes("password")
.and()
.withClient("gateway_client")
.secret(passwordEncoder.encode("123456"))
.accessTokenValiditySeconds(3600)
.resourceIds("gateway", "game-service")
.scopes("read", "write")
.authorizedGrantTypes("password");
}
/**
* 配置哪些可以访问认证服务器
*
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager); //authenticationManager校验传递进来的用户是否合法
}
}
3.1. 上面配置是为了测试 放在了内存里 然而这样在生产环境肯定是不行的!因为我们要对客户开放注册Client!我们要实现Client的注册,动态的加载到Oauth服务中。所以要实现Client的持久化,这里我们使用Mysql 建议直接先跳过这里的步骤 先把流程走通 再倒回来 配置mysql持久化!!!
3.2. pom文件添加依赖
```
<!--整合jdbc 实现服务数据持久化-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
```
3.3. 导入sql脚本(这里使用mysql)
```sql
/*
Navicat Premium Data Transfer
Source Server : 192.168.2.230
Source Server Type : MySQL
Source Server Version : 50725
Source Host : 192.168.2.230:3306
Source Schema : oauth
Target Server Type : MySQL
Target Server Version : 50725
File Encoding : 65001
Date: 02/07/2020 11:44:17
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for authority
-- ----------------------------
DROP TABLE IF EXISTS `authority`;
CREATE TABLE `authority` (
`id` bigint(11) NOT NULL COMMENT ‘权限id‘,
`authority` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘权限‘,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for credentials
-- ----------------------------
DROP TABLE IF EXISTS `credentials`;
CREATE TABLE `credentials` (
`id` bigint(11) NOT NULL COMMENT ‘凭证id‘,
`enabled` tinyint(1) NOT NULL COMMENT ‘是否可用‘,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘用户名‘,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘密码‘,
`version` int(11) NULL DEFAULT NULL COMMENT ‘版本号‘,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for credentials_authorities
-- ----------------------------
DROP TABLE IF EXISTS `credentials_authorities`;
CREATE TABLE `credentials_authorities` (
`credentials_id` bigint(20) NOT NULL COMMENT ‘凭证id‘,
`authorities_id` bigint(20) NOT NULL COMMENT ‘权限id‘
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for oauth_access_token
-- ----------------------------
DROP TABLE IF EXISTS `oauth_access_token`;
CREATE TABLE `oauth_access_token` (
`token_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘加密的access_token的值‘,
`token` longblob NULL COMMENT ‘OAuth2AccessToken.java对象序列化后的二进制数据‘,
`authentication_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘加密过的username,client_id,scope‘,
`user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘登录的用户名‘,
`client_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端ID‘,
`authentication` longblob NULL COMMENT ‘OAuth2Authentication.java对象序列化后的二进制数据‘,
`refresh_token` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘加密的refresh_token的值‘
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for oauth_approvals
-- ----------------------------
DROP TABLE IF EXISTS `oauth_approvals`;
CREATE TABLE `oauth_approvals` (
`userId` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘登录的用户名‘,
`clientId` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘客户端ID‘,
`scope` varchar(255)