1.简介
在上一章中已经介绍了Spring Security Oauth2的基本理论知识及其使用场景,本章节中注解介绍在Spring Cloud 中如何通过Oauth2来实现微服统一认证授权。
1.1解决方案
本文中主要用到以下解决方案:
- 基于无状态令牌(jwt)的认证方案,服务端无需保存用户登陆状态;
- 基于spring security框架 + oauth2协议 搭建;
为什么使用jwt方式?
避免每次请求都需要远程调用认证授权服务,认证授权服务只验证一次,返回JWT。返回的 JWT 包含了用户的所有信息,包括权限信息。
1.2案例工程架构
三个工程:
- eureka-server:注册服务中心,端口8888。(在此前文章中已经搭建过,本文中不演示搭建过程)
- auth-server:负责授权,授权需要用户提供客户端的 clientId 和 password,以及授权用户的username和password。这些信息准备无误之后,auth-service 返回JWT,该 JWT 包含了用户的基本信息和权限点信息,并通过 RSA 加密。
- auth-client:鉴权客户端,公共依赖。其他所有资源服务引入
- user-server:作为资源服务,它的资源以及被保护起来了,需要相应的权限才能访问。user-server 服务得到用户请求的 JWT 后,先通过公钥解密JWT,得到该JWT对应的用户的信息和用户的权限信息,再判断该用户是否有权限访问该资源
- order-server:同上
工程架构图:
工程依赖关系:
2.构建auth-server工程
2.1添加maven依赖
新建一个auth-server模块,并添加以下依赖:
<?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>spring-cloud-oauth2</artifactId>
<groupId>com.hxmec</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>auth-server</artifactId>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.8.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2创建数据表
工程所需要的的表主要有以下几个:
主要用于存放 oauth2 协议中的client信息,颁发的 access token,refresh token 等信息。
oauth2 相关的表说明参考http://andaily.com/spring-oauth-server/db_table_description.html 。演示工程中Access Token以jwt形式存储,所以实际只用到oauth_client_details表,以及sys_user用户信息表。如果改用用jdbc方式存储,则需要用到其他表。
建表语句如下:
-- 客户端应用注册详情
create table oauth_client_details (
client_id VARCHAR(256) PRIMARY KEY, -- 客户端应用的账号
resource_ids VARCHAR(256), -- 客户端应用可访问的资源服务器列表,(空代表所有资源服务器都可以访问)
client_secret VARCHAR(256), -- 客户端应用的密码
scope VARCHAR(256), -- 资源服务器拥有的所有权限列表 (get add delete update)
authorized_grant_types VARCHAR(256), -- 客户端支持的授权码模式列表
web_server_redirect_uri VARCHAR(256), -- 授权码模式,申请授权码后重定向的uri.
authorities VARCHAR(256),
access_token_validity INTEGER, -- 设置颁发token的有效期
refresh_token_validity INTEGER, -- 颁发refresh_token的有效期(不设置不会同时颁发refresh_token)
additional_information VARCHAR(4096),
autoapprove VARCHAR(256) -- 设置为true,授权码模式下自动授权
);
create table oauth_client_token (
token_id VARCHAR(256),
token BLOB,
authentication_id VARCHAR(256) PRIMARY KEY,
user_name VARCHAR(256),
client_id VARCHAR(256)
);
-- 存放颁发的token
create table oauth_access_token (
token_id VARCHAR(256),
token BLOB,
authentication_id VARCHAR(256) PRIMARY KEY,
user_name VARCHAR(256),
client_id VARCHAR(256),
authentication BLOB,
refresh_token VARCHAR(256)
);
create table oauth_refresh_token (
token_id VARCHAR(256),
token BLOB,
authentication BLOB
);
-- 授权码模式下,存放颁发的授权码
create table oauth_code (
code VARCHAR(256), authentication BLOB
);
create table oauth_approvals (
userId VARCHAR(256),
clientId VARCHAR(256),
scope VARCHAR(256),
status VARCHAR(10),
expiresAt DATETIME,
lastModifiedAt DATETIME
);
CREATE TABLE `sys_user` (
`id` bigint(32) NOT NULL,
`username` varchar(100) DEFAULT NULL,
`password` varchar(200) DEFAULT NULL,
`enable_` tinyint(1) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`mobile` varchar(20) DEFAULT NULL,
`del_flag` tinyint(1) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`create_user` bigint(32) DEFAULT NULL,
`modified_time` datetime DEFAULT NULL,
`modified_user` bigint(32) DEFAULT NULL,