美文网首页
旧的Spring Security OAuth已停止维护,全面拥

旧的Spring Security OAuth已停止维护,全面拥

作者: JEECG | 来源:发表于2024-03-05 16:24 被阅读0次

    Spring Authorization Server 替换 Shiro 指引

    背景

    • Spring 团队正式宣布 Spring Security OAuth 停止维护,该项目将不会再进行任何的迭代
      image.png
    • 目前 Spring 生态中的 OAuth2 授权服务器是 Spring Authorization Server 已经可以正式生产使用
    • 作为 SpringBoot 3.0 的最新权限方案,JeecgBoot springboot3_sas分支,已经完成了采用Spring Authorization Server 替换 Shiro工作。

    JeecgBoot SAS分支

    • Date: 2024-01-17
    • 技术栈: SpringBoot3+ Spring Authorization Server+jdk18

    源码下载:

    登录对接

    jeecg 基于Spring Authorization Server扩展了四种登录实现,加上默认提供的四种,共计有8种登录方式,额外还有OpenID Connect模式。本文不讲解授权码模式、客户端模式、刷新码模式、设备码模式、OpenID Connect模式,只会讲解jeecg实际应用了的四种扩展模式,其它模式请查阅Spring Authorization Server官方原文。

    https://docs.spring.io/spring-authorization-server/reference/overview.html

    注意:OpenID Connect应当仅为认证阶段使用,不可作为权限校验阶段使用。

    密码模式和APP模式

    密码模式在Oauth2.1协议中被放弃,Spring Authorization Server并没有对该模式提供实现,该实现是基于Spring Authorization Server提供的扩展入口实现的。

    密码模式实现源码:package org.jeecg.config.security.password;

    APP模式实现源码:package org.jeecg.config.security.app;

    密码模式与APP模式实现完全一致,不过防止额外需求偏差,所以进行了分开实现。

    请求地址:{baseUrl} /oauth2/token

    请求方法:POST

    请求头:

    请求头名称 请求头值
    Authorization Basic base64(clientId:clientSecret)(此处需要自行替换)
    Content-Type application/x-www-form-urlencoded

    请求参数:

    参数名称 参数值
    grant_type password/app (password为PC端使用,app为移动端使用)
    username 用户名
    password 密码

    响应内容:

    参数名称 参数含义
    access_token 访问token,在被限制访问的接口请求中添加Authorization: Bearer access_token
    refersh_token 刷新token,用于刷新码模式获取新的access_token
    userInfo 当前登录用户信息
    ... 其它内容不作详解,请查看源码

    phone模式

    phone模式用于手机+验证码登录场景。

    phone模式实现源码:package org.jeecg.config.security.phone;

    请求地址:{baseUrl} /oauth2/token

    请求方法:POST

    请求头:

    请求头名称 请求头值
    Authorization Basic base64(clientId:clientSecret)(此处需要自行替换)
    Content-Type application/x-www-form-urlencoded

    请求参数:

    参数名称 参数值
    grant_type 固定为phone
    mobile 手机号
    captcha 验证码

    响应内容:

    参数名称 参数含义
    access_token 访问token,在被限制访问的接口请求中添加Authorization: Bearer access_token
    refersh_token 刷新token,用于刷新码模式获取新的access_token
    userInfo 当前登录用户信息
    ... 其它内容不作详解,请查看源码

    social模式

    任何一个用户中心端(比如微信、微博、github、gitee)对外提供的对接方式都是授权码模式、OpenID Connect模式,最终获取到一段用户信息(比如用户名、头像地址、邮箱),但是其实并没有办法拿着这段信息在当前系统中访问受限资源,以前都是手搓token或者其它手段来得到受限访问的权限,这种方法不可靠也不安全,而且也不易维护。

    jeecg针对以上场景,基于Spring Authorization Server扩展了social模式,用于处理获取三方用户信息后,再获取当前系统的访问凭证。

    social模式实现源码:package org.jeecg.config.security.social;

    提示:文档中只讲解social模式的应用,不讲解从三方登录到应用social模式的全流程,jeecg前后端均已实现,细节请查看源码。

    请求地址:{baseUrl} /oauth2/token

    请求方法:POST

    请求头:

    请求头名称 请求头值
    Authorization Basic base64(clientId:clientSecret)(此处需要自行替换)
    Content-Type application/x-www-form-urlencoded

    请求参数:

    参数名称 参数值
    grant_type 固定为social
    token 可获取用户信息的凭证
    thirdType 三方来源

    响应内容:

    参数名称 参数含义
    access_token 访问token,在被限制访问的接口请求中添加Authorization: Bearer access_token
    refersh_token 刷新token,用于刷新码模式获取新的access_token
    userInfo 当前登录用户信息
    ... 其它内容不作详解,请查看源码

    权限校验

    可用于方法或类上,将基于注解的权限code,针对性处理方法或当前类的所有接口进行权限拦截。

    基于角色

    // shiro用法
    @RequiresRoles("admin")
     
    // 可替换为 spring authorization server 用法
    @PreAuthorize("jps.requiresRoles('admin')")
    

    基于权限

    // shiro用法
    @RequiresPermissions("sys:role") 
    
    
    // 可替换为 spring authorization server 用法
    @PreAuthorize("jps.requiresPermissions('sys:role')")
    

    角色和权限组合使用

    - @PreAuthorize("@jps.requiresPermissions('system:quartzJob:add') or @jps.requiresRoles('admin')")
    

    免登录配置

    jeecg:
      shiro:
        excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/jmreport/bigscreen2/**
    
    
    
    
    # 替换为
    security:
      oauth2:
        client:
          ignore-urls:
            - /test/jeecgDemo/demo3
            - /test/jeecgDemo/redisDemo/**
            - /jmreport/bigscreen2/**
    

    升级小技巧

    搜索 替换为
    org.apache.shiro.SecurityUtils org.jeecg.config.security.utils.SecureUtil
    (LoginUser) SecurityUtils.getSubject().getPrincipal() SecureUtil.currentUser()
    org.apache.shiro.authz.annotation.RequiresRoles org.springframework.security.access.prepost.PreAuthorize
    org.apache.shiro.authz.annotation.RequiresPermissions org.springframework.security.access.prepost.PreAuthorize
    @RequiresPermissions @PreAuthorize("jps.requiresPermissions('xxx')")
    @RequiresRoles @PreAuthorize("@jps.requiresRoles('xxx')")

    升级SQL

    切换springboot3_sas分支的Spring Authorization Server,需要执行升级sql

    CREATE TABLE `oauth2_registered_client` (
      `id` varchar(100) NOT NULL,
      `client_id` varchar(100) NOT NULL,
      `client_id_issued_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `client_secret` varchar(200) DEFAULT NULL,
      `client_secret_expires_at` timestamp NULL DEFAULT NULL,
      `client_name` varchar(200) NOT NULL,
      `client_authentication_methods` varchar(1000) NOT NULL,
      `authorization_grant_types` varchar(1000) NOT NULL,
      `redirect_uris` varchar(1000) DEFAULT NULL,
      `post_logout_redirect_uris` varchar(1000) DEFAULT NULL,
      `scopes` varchar(1000) NOT NULL,
      `client_settings` varchar(2000) NOT NULL,
      `token_settings` varchar(2000) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
    
    
    INSERT INTO `oauth2_registered_client`
    (`id`,
    `client_id`,
    `client_id_issued_at`,
    `client_secret`,
    `client_secret_expires_at`,
    `client_name`,
    `client_authentication_methods`,
    `authorization_grant_types`,
    `redirect_uris`,
    `post_logout_redirect_uris`,
    `scopes`,
    `client_settings`,
    `token_settings`)
    VALUES
    ('3eacac0e-0de9-4727-9a64-6bdd4be2ee1f',
    'jeecg-client',
    now(),
    'secret',
    null,
    '3eacac0e-0de9-4727-9a64-6bdd4be2ee1f',
    'client_secret_basic',
    'refresh_token,authorization_code,password,app,phone,social',
    'http://127.0.0.1:8080/jeecg-',
    'http://127.0.0.1:8080/',
    '*',
    '{"@class":"java.util.Collections$UnmodifiableMap","settings.client.require-proof-key":false,"settings.client.require-authorization-consent":true}',
    '{"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",300000.000000000],"settings.token.access-token-format":{"@class":"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat","value":"self-contained"},"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000],"settings.token.authorization-code-time-to-live":["java.time.Duration",300000.000000000],"settings.token.device-code-time-to-live":["java.time.Duration",300000.000000000]}');
    

    常用API

    1. 获取登录用户信息

    LoginUser sysUser = SecureUtil.currentUser();

    相关文章

      网友评论

          本文标题:旧的Spring Security OAuth已停止维护,全面拥

          本文链接:https://www.haomeiwen.com/subject/bysdzdtx.html