五、SpringSecurity OAuth2扩展手机验证码授权模式

这篇具有很好参考价值的文章主要介绍了五、SpringSecurity OAuth2扩展手机验证码授权模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

代码

代码仓库:地址

代码分支:lesson5

简介

在上一篇文章中,我们使用SpringSecurity OAuth2搭建了一套授权服务,对业务系统进行统一授权管理。OAuth提供了四种授权方式:

  • 授权码模式(authorization_code)
  • 简化模式(implicit)
  • 客户端(client_credentials)
  • 密码(password)

在实际业务中上述四种模式不能满足所有要求,例如业务系统接入了短信验证码登录方式,需要进行扩展满足业务需求

手机验证码登录

原理分析

SpringSecurity OAuth在使用@EnableAuthorizationServer注解会自动装配TokenEndpoint对象,这个对象会提供一个POST /oauth/token接口,我们以密码授权模式分析调用流程,如下所示:

五、SpringSecurity OAuth2扩展手机验证码授权模式

用户在时间海绵博客发起用户名密码登录请求,时间海绵博客服务器端接收到请求后,调用OAuth协议中的密码授权模式发送请求到OAuth授权服务器,请求信息如下:

client_id:blog
client_secret:blog
grant_type:password
username:admin
password:admin

在ClientCredentialsTokenEndpointFilter过滤器中对客户端信息(client_id和client_secret)进行校验,授权成功后才能访问TokenEndpoint接口(这里要注意,对于OAuth授权服务器来说,过滤链主要完成对客户端信息的校验,用户信息在TokenEndpoint中进行校验,这是因为不同的授权模式关注的用户信息类型不同,需要具体问题具体分析)。

在TokenEndpoint中依据验证的客户端信息以及请求的授权模式进行对比,校验客户端是否有权限进行特定类型授权请求,校验通过后委托给TokenGranter组件进行具体授权模式校验,如上图所示,ResourceOwnerPasswordTokenGranter负责对密码授权模式请求校验,SpringSecurity OAuth还提供了以下实现来校验授权请求:

  • AuthorizationCodeTokenGranter负责校验授权码模式(authorization_code)请求
  • ClientCredentialsTokenGranter负责校验客户端模式(client_credentials)请求
  • ImplicitTokenGranter负责校验简化模式(implicit)请求
  • ResourceOwnerPasswordTokenGranter负责校验密码模式(password)请求

TokenGranter校验成功将返回AccessToken信息,后续客户端可以使用AccessToken信息获取到授权用户信息完成对应操作。

通过上述可以知道,如果要扩展实现短信验证码模式,需要自定义实现TokenGranter组件来校验手机验证码授权请求,TokenGranter定义如下所示:

public interface TokenGranter {
     对授权类型以及请求参数进行处理,如果成功则返回AccessToken信息
	OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest);
}

手机验证码模式代码实现

实现一个继承ToeknGranter接口的类,通过分析已有的TokenGranter子类,我们可以很容易实现,定义一个SmsCodeTokenGranter类,代码实现如下所示:

public class SmsCodeTokenGranter extends AbstractTokenGranter {

    /// 授权模式类型,需要与请求字段grant_type的值相等才会进入处理
    private static final String GRANT_TYPE = "sms_code";
    /// 验证手机与验证码信息是否匹配,这里只是简单的进行匹配处理,判断是否是否为15000000000,验证码是否为:888888
    private final PhoneSmsCodeService phoneSmsCodeService;

    public SmsCodeTokenGranter(AuthorizationServerTokenServices tokenServices,
            ClientDetailsService clientDetailsService,
            OAuth2RequestFactory requestFactory, PhoneSmsCodeService phoneSmsCodeService
    ) {
        super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
        this.phoneSmsCodeService = phoneSmsCodeService;
    }

    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {

        Map<String, String> parameters = new LinkedHashMap(tokenRequest.getRequestParameters());

        String mobile = parameters.get("mobile"); // 手机号
        String code = parameters.get("code"); // 短信验证码
        ///对参数进行基础校验
        if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(code)) {
            throw new InvalidGrantException("授权请求参数异常");
        }
        /// 校验手机验证码是否符合要求
        if (!phoneSmsCodeService.checkSmsCode(mobile, code)) {
            throw new InvalidGrantException("授权请求参数异常");
        }

        /// 这里为了简单直接硬编码写入用户信息,通常需要在数据库中取出用户相关信息
        List<GrantedAuthority> roles = new ArrayList<>();
        roles.add( new SimpleGrantedAuthority("user"));
        User user = new User(mobile, "", roles);
        /// 授权模式
        UsernamePasswordAuthenticationToken userAuth = new UsernamePasswordAuthenticationToken(user, null, roles);
        userAuth.setAuthenticated(true);
        OAuth2Request storedOAuth2Request = this.getRequestFactory()
                .createOAuth2Request(client, tokenRequest);
        return new OAuth2Authentication(storedOAuth2Request, userAuth);
    }
}
继承AbstractTokenGranter抽象类(该类继承了TokenGranter接口),我们只需要关注核心逻辑"验证手机验证码信息是否正确",校验正确将返回一个OAuth2Authentication对象,这个对象包含了用户信息以及OAuth2请求信息。
完成这一步后,我们需要将SmsCodeTokenGranter装配到TokenEndpoint组件中对sms_code授权类型进行校验处理,配置逻辑如下:
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .authenticationManager(authenticationManager)/// 用于密码模式验证时需要提供客户端身份验证信息
                .reuseRefreshTokens(false);
         取出系统中的四种模式
        List<TokenGranter> granters = new ArrayList<>(Arrays.asList(endpoints.getTokenGranter()));
        /// 添加手机验证码的授权模式
        granters.add(new SmsCodeTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), phoneSmsCodeService));
        /// 这是一个组装模式,实现了TokenGranter接口,循环调用List中的TokenGranter组件进行校验处理,直到返回验证成功信息或者是异常信息
        CompositeTokenGranter compositeTokenGranter = new CompositeTokenGranter(granters);
        endpoints.tokenGranter(compositeTokenGranter);
    }

上述在AuthorizationServerConfigurerAdapter配置类中进行,具体参见代码。

运行校验

需要注意,这是一个新的授权模式,因此需要先授权客户端拥有手机短信验证模式请求权限,配置客户端的authorizedGrantTypes属性包含sms_code权限(这一步参见代码)。

启动服务,发送手机验证码授权请求POST /oauth/token,请求参数:

client_id:blog
client_secret:blog
grant_type:sms_code
mobile:15000000000
code:888888

返回参数信息:

{
    "access_token": "cf4243c1-085e-4f82-b733-03fb38c90a7c",
    "token_type": "bearer",
    "refresh_token": "01474dd1-c5c5-436b-98b1-8f146cde2391",
    "expires_in": 7199,
    "scope": "all user"
}

手机短信验证码授权模式验证成功,具体代码参见代码仓库。

总结

  • 扩展自定义授权模式,需要继承TokenGranter接口,实现具体校验逻辑
  • 将实现的自定义授权TokenGraner类装配到TokenEndpoint组件中
  • 特别注意需要将新的授权模式grantType信息授权给指定的客户端,不然客户端无法发送自定义授权模式请求,例如本案例中的sms_code请求

参考文档

  • 有来技术博客

联系方式

技术更新换代速度很快,我们无法在有限时间掌握全部知识,但我们可以在他人的基础上进行快速学习,学习也是枯燥无味的,加入我们学习牛人经验:

点击:加群讨论 文章来源地址https://www.toymoban.com/news/detail-514623.html

到了这里,关于五、SpringSecurity OAuth2扩展手机验证码授权模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringSecurity学习(八)OAuth2.0、授权服务器、资源服务器、JWT令牌的使用

    OAuth2是一个认证协议,SpringSecurity对OAuth2协议提供了响应的支持,开发者可以非常方便的使用OAuth2协议。 简介 四种授权模式 Spring Security OAuth2 GitHub授权登录 授权服务器与资源服务器 使用JWT OAuth是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密资源

    2024年02月02日
    浏览(60)
  • 【Oauth2.0 单点登录 + 第三方授权认证】用户认证、授权模式

    本文主要对 SpringSecurity Oauth 2.0 用户认证,授权码授权模式、密码授权模式,以及授权流程进行讲解 开发中,有些功能只有管理员才有,普通用户是没有的。即需要对用户的身份进行认证,是管理员还是普通用户。认证方式有两种: 身份认证: 用户在访问相应资源时对用户

    2023年04月08日
    浏览(65)
  • 自定义OAuth2组件实现对授权码登录模式的封装

    所谓OAuth2其实就是Open Authorization,即开放授权,是一种授权机制或者说是一种协议。 OAuth2允许用户授权第三方应用访问其存储在开放平台(授权服务器)中的数据而不需要提供密码 。授权服务器根据OAuth2协议标准制订一套授权的API,第三方网站接入开放平台之后即可通过其

    2024年02月05日
    浏览(38)
  • Oauth2.0四种授权模式适用场景和授权流程介绍以及个人的一些思考

    Oauth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准,先前曾经了解过在 spring-security-oauth2 中 Oauth 四种模式的实现,也通过 Shiro 实现了 Oauth 的授权流程。 目前 spring-security-oauth2 已经被逐步废弃, Spring 也提供了新的框架 spring-authorization-server ,整个框架基于

    2024年02月03日
    浏览(40)
  • 【安全】 阅读 RFC6749 及理解 Oauth2.0 下的授权码模式

    OAuth 2.0 规范来自 RFC6749。看了《Spring 微服务实战》对OAuth 2.0 的介绍后还是觉得存在一些翻译的问题。现在结合 RFC6749 一起重新梳理下。 1.1. 一个场景: o-stock 实现获取微信头像。 结论性的东西全部来自于该文档。 本文是主要以获取微信头像作为模型,对 Oauth2.0 知识点进行

    2024年02月11日
    浏览(43)
  • 深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计

    认证和授权是安全验证中的两个重要概念。认证是确认身份的过程,用于建立双方之间的信任关系。只有在认证成功的情况下,双方才可以进行后续的授权操作。授权则是在认证的基础上,确定用户或系统对资源的访问权限。 在设计一个权限认证框架时,可以考虑以下原则:

    2024年02月12日
    浏览(36)
  • 授权码 + PKCE 模式|OIDC & OAuth2.0 认证协议最佳实践系列【03】

    ​ 在上一篇文章中,我们介绍了 OIDC 授权码模式(点击下方链接查看), 本次我们将重点围绕 授权码 + PKCE 模式(Authorization Code With PKCE)进行介绍 ,从而让你的系统快速具备接入用户认证的标准体系。 OIDC OAuth2.0 认证协议最佳实践系列 02 - 授权码模式(Authorization Code)接

    2024年02月01日
    浏览(93)
  • SpringSecurity+OAuth2.0

    OAuth(Open Authorization)是一个关于授权(authorization)的开放网络标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容。OAuth 在全世界得到广泛应用,目前的版本是 2.0 版。 简单

    2024年02月13日
    浏览(41)
  • SpringSecurity之Oauth2介绍

    第三方认证技术方案最主要是解决 认证协议的通用标准问题 ,因为要实现跨系统认证,各系统之间要遵循一定的接口协议。 OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的

    2023年04月09日
    浏览(46)
  • SpringSecurity+Oauth2+JWT

    快速入门 1. 创建基础项目 file == new == project == Spring Initializr ==next == web(Spring Web)、Security(Spring Security) ==一直下一步 2. 编写代码进行测试 创建controller static下创建login.html、main.html 3. 启动项目进行测试 访问http://localhost:8080/login.html 会进入SpringSecurity框架自带的登入页面 用户默认

    2024年02月12日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包