Spring Boot、Spring Security、Oauth2实现的权限控制和认证服务

基于Spring Boot、Spring Security、Oauth2等实现的权限控制和认证服务、支持第三方oauth授权和获取资源信息功能等

一.简介

该项目是基于Spring Boot搭建而成,通过Spring Security以及Spring Security Oauth2等,实现RBAC权限模型。其中包含了登录授权功能,以及第三方oauth授权和获取资源信息功能等。

二.OAuth2 协议的授权模式介绍

1.授权码模式(Authorization Code)

功能最完整,流程最严密的授权模式。国内各大服务提供商(微信、QQ、微博、淘宝 、百度)都采用此模式进行授权。可以确定是用户真正同意授权。

2.简化模式(Implicit)

令牌是发放给浏览器的,oauth客户端运行在浏览器中 ,通过JS脚本去申请令牌。不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌 ,不需要先获取授权码。
直接可以一次请求就可得到令牌,在 redirect_uri 指定的回调地址中传递令牌( access_token )。

3.密码模式(Resource Owner Password Credentials)

将用户名和密码传过去,直接获取 access_token 。用户同意授权动作是在第三方应用上完成 ,而不是在认证服务器上。第三方应用申请令牌时,直接带着用户名密码去向认证服务器申请令牌。这种方式认证服务器无法断定用户是否真的授权了,用户名密码可能是第三方应用盗取来的。

4.客户端证书模式(Client credentials)

用得少。当一个第三应用自己本身需要获取资源(而不是以用户的名义),而不是获取用户的资源时,客户端模式十分有用。

三.令牌管理策略介绍

  • 内存存储采用的是 TokenStore 接口的默认实现类 InMemoryTokenStore , 开发时方便调试,适用单机版。
  • RedisTokenStore 将令牌存储到 Redis 非关系型数据库中,适用于并发高的服务。
  • JdbcTokenStore 基于 JDBC 将令牌存储到 关系型数据库中,可以在不同的服务器之间共享令牌。
  • JwtTokenStore (JSON Web Token)将用户信息直接编码到令牌中,这样后端可以不用存储它,资源服务器可以直接解析获取用户数据。

四.为什么使用jwt令牌方式

当认证服务器和资源服务器不是在同一工程时, 要使用 ResourceServerTokenServices 去远程请求认证服务器来校验
令牌的合法性,如果用户访问量较大时将会影响系统的性能。

此时,采用 JWT 格式就可以解决上面的问题。
因为当用户认证后获取到一个JWT令牌,而这个 JWT 令牌包含了用户基本信息,客户端只需要携带JWT访问资源服
务器,资源服务器会通过事先约定好的算法进行解析出来,然后直接对 JWT 令牌校验,不需要每次远程请求认证服
务器完成授权。

当然并不是说jwt管理令牌是最优的方式,该方式也是存在着一定的不足的…

五.后端技术选型:

  • Spring Boot 2.6.0
  • Spring Security 2.6.6
  • Spring Security oauth 2 2.2.6.RELEASE
  • jjwt 0.7.0
  • MyBatis 3.5.5
  • MyBatis-Plus 3.4.3.4
  • MySQL 5.1.30

六.后端项目结构:

主要的三个模块项目

  1. platform-auth-server即认证服务
  2. platform-common即公共服务
  3. platform-resources-server即资源服务
micai
    //认证服务
|-- platform-auth-server
|   |-- platform-auth-server.iml
|   |-- pom.xml
|   |-- src
|      |-- main
|           |-- java
|           |   |-- org
|           |       |-- micai
|           |           |-- platform
|           |               |-- authserver
|           |                   |-- AuthServerApplication.java
|           |                   |-- bo		//入参对象
|           |                   |   |-- UserQueryBo.java
|           |                   |-- config		//相关配置
|           |                   |   |-- AuthorizationServerConfiguration.java
|           |                   |   |-- JwtTokenEnhancer.java
|           |                   |   |-- PasswordEncoder.java
|           |                   |   |-- TokenConfig.java
|           |                   |   |-- WebSecurityConfig.java
|           |                   |-- entity		//相关实体类
|           |                   |   |-- Permission.java
|           |                   |   |-- Role.java
|           |                   |   |-- RolePermission.java
|           |                   |   |-- User.java
|           |                   |   |-- UserRole.java
|           |                   |-- filter		//相关过滤器
|           |                   |   |-- JWTAuthenticationFilter.java
|           |                   |   |-- JWTLoginFilter.java
|           |                   |-- handler		//相关处理器
|           |                   |   |-- CustomAuthenticationFailureHandler.java
|           |                   |   |-- Http401AuthenticationEntryPoint.java
|           |                   |   |-- MyMetaObjectHandler.java
|           |                   |-- interceptor		//相关拦截器
|           |                   |   |-- PlusInterceptor.java
|           |                   |-- mapper		//mapper文件
|           |                   |   |-- PermissionMapper.java
|           |                   |   |-- RoleMapper.java
|           |                   |   |-- RolePermissionMapper.java
|           |                   |   |-- UserMapper.java
|           |                   |   |-- UserRoleMapper.java
|           |                   |-- provider		//security相关提供器
|           |                   |   |-- CustomAuthenticationProvider.java
|           |                   |-- service			//相关service类
|           |                       |-- PermissionService.java
|           |                       |-- RolePermissionService.java
|           |                       |-- RoleService.java
|           |                       |-- UserRoleService.java
|           |                       |-- UserService.java
|           |                       |-- impl
|           |                           |-- GrantedAuthorityImpl.java
|           |                           |-- PermissionServiceImpl.java
|           |                           |-- RolePermissionServiceImpl.java
|           |                           |-- RoleServiceImpl.java
|           |                           |-- UserDetailsServiceImpl.java
|           |                           |-- UserRoleServiceImpl.java
|           |                           |-- UserServiceImpl.java
|           |-- resources
|               |-- application-dev.yml
|               |-- application-pro.yml
|               |-- application.yml
    //公共服务
|-- platform-common
|   |-- platform-common.iml
|   |-- pom.xml
|   |-- src
|       |-- main
|           |-- java
|           |   |-- org
|           |       |-- micai
|           |           |-- platform
|           |               |-- common
|           |                   |-- base		//公共包
|           |                       |-- WebStarterAutoConfig.java
|           |                       |-- config		//公共配置
|           |                       |   |-- MicaiPlatformOauthConfig.java
|           |                       |   |-- MicaiPlatformRequestMatcher.java
|           |                       |   |-- MicaiPlatformResourcesConfig.java
|           |                       |   |-- MicaiPlatformTokenConfig.java
|           |                       |-- constant		//常量和常枚举
|           |                       |   |-- ConstantCode.java
|           |                       |   |-- ConstantEnum.java
|           |                       |-- controller		//异常处理controller
|           |                       |   |-- ExceptionController.java
|           |                       |-- exception		//异常处理和自定义异常
|           |                       |   |-- GlobalExceptionHandler.java
|           |                       |   |-- MyAuthException.java
|           |                       |   |-- PlatformException.java
|           |                       |-- result			//自定义返回对象
|           |                       |   |-- Result.java
|           |                       |   |-- UploadResult.java
|           |                       
|           |-- resources
|               |-- META-INF
|                   |-- spring.factories
    //资源服务
|-- platform-resources-server
|   |-- platform-resources-server.iml
|   |-- pom.xml
|   |-- src
|       |-- main
|           |-- java
|           |   |-- org
|           |       |-- micai
|           |           |-- platform
|           |               |-- resourcesserver
|           |                   |-- ResourcesServerApplication.java
|           |                   |-- bo			//入参对象
|           |                   |   |-- MenuDelBo.java
|           |                   |   |-- MenuSaveBo.java
|           |                   |   |-- MenuUpdateBo.java
|           |                   |   |-- OrganDelBo.java
|           |                   |   |-- OrganFindBo.java
|           |                   |   |-- OrganSaveBo.java
|           |                   |   |-- OrganUpdateBo.java
|           |                   |   |-- PermissionDelBo.java
|           |                   |   |-- PermissionFindBo.java
|           |                   |   |-- PermissionMenuDelBo.java
|           |                   |   |-- PermissionMenuSaveBo.java
|           |                   |   |-- PermissionMenuUpdateBo.java
|           |                   |   |-- PermissionSaveBo.java
|           |                   |   |-- PermissionUpdateBo.java
|           |                   |   |-- RoleDelBo.java
|           |                   |   |-- RoleFindBo.java
|           |                   |   |-- RolePermissionDelBo.java
|           |                   |   |-- RolePermissionSaveBo.java
|           |                   |   |-- RolePermissionUpdateBo.java
|           |                   |   |-- RoleSaveBo.java
|           |                   |   |-- RoleUpdateBo.java
|           |                   |   |-- UserDelBo.java
|           |                   |   |-- UserFindBo.java
|           |                   |   |-- UserQueryBo.java
|           |                   |   |-- UserRoleDelBo.java
|           |                   |   |-- UserRoleSaveBo.java
|           |                   |   |-- UserRoleUpdateBo.java
|           |                   |   |-- UserSaveBo.java
|           |                   |   |-- UserUpdateBo.java
|           |                   |-- config			//相关配置类
|           |                   |   |-- CodeGenerator.java
|           |                   |   |-- PasswordEncoder.java
|           |                   |   |-- ResourceServerConfig.java
|           |                   |   |-- SiteOptions.java
|           |                   |   |-- SwaggerConfig.java
|           |                   |   |-- TokenConfig.java
|           |                   |   |-- WebSecurityConfig.java
|           |                   |-- controller		//表现层
|           |                   |   |-- BaseController.java
|           |                   |   |-- PermissionController.java
|           |                   |   |-- RoleController.java
|           |                   |   |-- RolePermissionController.java
|           |                   |   |-- UploadController.java
|           |                   |   |-- UserController.java
|           |                   |   |-- UserRoleController.java
|           |                   |-- dto
|           |                   |   |-- UserAuthenticationDto.java
|           |                   |-- entity
|           |                   |   |-- Permission.java
|           |                   |   |-- Role.java
|           |                   |   |-- RolePermission.java
|           |                   |   |-- User.java
|           |                   |   |-- UserRole.java
|           |                   |-- filter			//相关自定义过滤器
|           |                   |   |-- AuthHeaderFilter.java
|           |                   |   |-- JWTAuthenticationFilter.java
|           |                   |-- handler			//相关自定义处理器
|           |                   |   |-- Http401AuthenticationEntryPoint.java
|           |                   |   |-- MyMetaObjectHandler.java
|           |                   |-- interceptor		//相关拦截器
|           |                   |   |-- PlusInterceptor.java
|           |                   |-- mapper
|           |                   |   |-- PermissionMapper.java
|           |                   |   |-- RoleMapper.java
|           |                   |   |-- RolePermissionMapper.java
|           |                   |   |-- UserMapper.java
|           |                   |   |-- UserRoleMapper.java
|           |                   |-- provider		//自定义security的提供器
|           |                   |   |-- CustomAuthenticationProvider.java
|           |                   |-- service			//相关的service
|           |                   |   |-- PermissionService.java
|           |                   |   |-- RolePermissionService.java
|           |                   |   |-- RoleService.java
|           |                   |   |-- UserRoleService.java
|           |                   |   |-- UserService.java
|           |                   |   |-- impl
|           |                   |       |-- GrantedAuthorityImpl.java
|           |                   |       |-- PermissionServiceImpl.java
|           |                   |       |-- RolePermissionServiceImpl.java
|           |                   |       |-- RoleServiceImpl.java
|           |                   |       |-- UserDetailsServiceImpl.java
|           |                   |       |-- UserRoleServiceImpl.java
|           |                   |       |-- UserServiceImpl.java
|           |                   |-- utils		//相关工具类
|           |                   |   |-- ApplicationUtil.java
|           |                   |   |-- AuthenticationManger.java
|           |                   |   |-- JwtHelper.java
|           |                   |   |-- MD5.java
|           |                   |-- vo			//返回前端对象
|           |                       |-- OrganListVo.java
|           |                       |-- PermissionListVo.java
|           |                       |-- RoleListVo.java
|           |                       |-- UserListVo.java
|           |-- resources
|               |-- application-dev.yml
|               |-- application-pro.yml
|               |-- application.yml
|               |-- logback-spring.xml
|-- pom.xml

七.相关配置解读:

platform-auth-server:

micai-platform-auth:
  #jwt-token登录相关配置
  token:
    #sign key
    sign-key: micai-security-@Jwt!&Secret^#
    #jwt 过期时间 单位:分钟
    timeout: 60
    # token名称
    token-name: Authorization
    # token前缀
    token-prefix: Bearer
  #oauth
  oauth-auth:
    #sign key
    sign-key: micai-oauth2-@Jwt!&Secret^#

platform-resources-server:

micai-platform-auth:
  #jwt相关配置
  token:
    #sign key
    sign-key: micai-security-@Jwt!&Secret^#
    #jwt 过期时间 单位:分钟
    timeout: 60
    # token名称
    token-name: Authorization
    # token前缀
    token-prefix: Bearer

  oauth-resources:
    #sign key
    sign-key: micai-oauth2-@Jwt!&Secret^#
    #资源id
    resource-ids: resources-server
    #过滤器匹配路径 可以使用**
    request-matcher:
      - /demo/**
      - /user/list

注意:

  • 在oauth-resources. request-matcher下配置了的路径,代表该接口是需要携带oauth生成的access_token,其他默认的接口是需要携带登录生成的token
  • 认证服务和资源服务配置的sign-key需要统一,不然会导致携带的token无法获取对应的资源

八.项目流程图:

spring boot 集成 spring security spring boot security oauth2_java

本系统登录授权流程:

  1. 调用登录接口http://localhost:8080/login 返回token令牌
curl --location --request POST 'http://localhost:8080/login' \
--header 'Content-Type: application/json' \
--data-raw '{"username":"root","password":"root"}'

2.携带返回的token信息,访问需要获取资源接口

第三方应用授权流程:

授权码模式流程:
  1. 调用登录接口http://localhost:8080/login 返回token令牌
curl --location --request POST 'http://localhost:8080/login' \
--header 'Content-Type: application/json' \
--data-raw '{"username":"root","password":"root"}'


2.携带返回的token信息,访问oauth2授权接口,使用授权码模式web_server_redirect_uri地址并且拼接了授权码信息

curl --location --request GET 'http://localhost:8080/oauth/authorize?response_type=code&client_id=pc' \
--header 'Authorization: Bear xxxxxx'

如图所示:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9oH0CXda-1676523779300)(./doc/README.assets/image-20221228140017204.png)]

3.根据获取的授权码信息,调用获取access_token信息http://localhost:8080/oauth/token?grant_type=authorization_code&client_id=pc&client_secret=admin&code=fQxVEU

curl --location --request POST 'http://localhost:8080/oauth/token?grant_type=authorization_code&client_id=pc&client_secret=admin&code=fQxVEU'

返回的信息,如下:

{
   		           "access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb20iOiJsaXVjb25nIiwid2l0aCI6Im1pY2FpIiwiYXVkIjpbInJlc291cmNlcy1zZXJ2ZXIiXSwidXNlcl9uYW1lIjoiMS1yb290LVt",
"token_type": "bearer",
"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb20iOiJsaXVjb25nIiwid2l0aCI6Im1pY2FpIiwiYXVkIjpbInJlc291cmNlcy1zZXJ2ZXIiXSwidXNlcl9uYW1lIjoiMS1yb290LVtcIlJPTEVfcm9vdFwiLFwi",
    "expires_in": 43199,
    "scope": "pc",
    "author": "liucong",
    "jti": "cfc312f6-c38f-4670-9140-9985372cb7c9"
}

access_token:返回的token令牌,可以访问对应资源服务;

token_type:token类型,token前缀

expires_in:过期时间

scope:作用范围

author:通过实现TokenEnhancer,添加自定义信息

jti:jwt唯一标识

4.携带access_token信息,访问需要获取资源接口

密码模式流程:

调用接口地址

curl --location --request POST 'http://localhost:8080/oauth/token?username=root&password=root&grant_type=password&client_id=pc&client_secret=admin'

返回对象,返回相关的access_token 、 expires_in 、 scope 等相关信息,如授权码模式

简化模式流程:

调用接口地址

http://localhost:8080/oauth/authorize?response_type=token&client_id=pc

会跳转到指定的 redirect_uri ,回调路径携带着令牌 access_token 、 expires_in 、 scope 等相关信息,如图所示:

spring boot 集成 spring security spring boot security oauth2_Spring Boot_02

客户端模式流程:

该使用的情况比较少,大家可以自行体验

九.swagger地址:

我们使用的是knife4j

Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j (xiaominfo.com)

platform-auth-server:http://localhost:8080/doc.html

platform-resources-server:http://localhost:8081/doc.html