Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试

这篇具有很好参考价值的文章主要介绍了Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. Spring boot 与Spring authorization Server集成流程说明

1. 创建项目
2. 添加依赖
3. 初始化数据库(用户授权确认表、用户认证信息表和客户端信息表)
4. 创建AuthorizationConfig(名字自定)类
5. 配置认证端点过滤器链,添加身份认证过滤器了、密码解析器、jws相关配置和认证服务设置
6. 配置上添加@Configuration、@EnableWebSecurity和@EnableMethodSecurity注解
7. 添加一个接口,将登录和用户授权确认页面请求转发至自定义的页面
8. 在application.yml中配置数据源信息
9. 添加自定义页面相关静态文件

2. 细节补充

在上一篇文章中的AuthorizationConfig.java配置类中,类上有三个注解,分别是@Configuration、@EnableWebSecurity和@EnableMethodSecurity注解,虽然在类中有注释,但是这里在细讲一下,同时放一下官网的说明

  1. @EnableWebSecurity
  1. 加载了WebSecurityConfiguration配置类, 配置安全认证策略。
  2. 加载了AuthenticationConfiguration, 配置了认证信息。
  1. @EnableMethodSecurity 官网文档说明

默认启用方法级别的安全校验

  1. 设置注解属性 jsr250Enabled = true 是为了启用JSR250注解支持,例如@RolesAllowed、@PermitAll和@DenyAll注解
  2. 设置属性securedEnabled = true 是为了启用@Secured注解支持,不设置属性则添加Secured注解无效
  1. @Configuration
    文档说明地址
    在Spring security 6.0 版本及之后版本中将@Configuration注解从@EnableWebSecurity, @EnableMethodSecurity, @EnableGlobalMethodSecurity 和 @EnableGlobalAuthentication 中移除,使用这些注解需手动添加 @Configuration 注解

3. 测试

1. 授权码模式获取token

该流程上一章已经说过了,本篇文章就大概过一下

1. 组装url发起授权请求

http://127.0.0.1:8080/oauth2/authorize?client_id=messaging-client&response_type=code&scope=message.read&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Flogin%2Foauth2%2Fcode%2Fmessaging-client-oidc

参数解释

client_id:客户端的id
response_type:授权码模式固定为code
scope:请求授权的范围
redirect_uri:回调地址

2. 重定向至登录页面

Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

3. 重定向至回调地址

该客户端已经经过用户授权确认了,授权确认信息表中已存在,所以直接重定向至回调地址
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

4. 复制code至postman发起请求

Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet
添加Basic Auth(客户端id和客户端秘钥)

grant_type: 在授权码模式中固定为authorization_code
redirect_uri:与第一步请求授权时携带的redirect_uri一致,并且是严格匹配模式,客户端配置中不能只配置一个域名
code:重定向至redirect_uri携带的code参数

2. 刷新token

Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

上一步通过授权码模式获取了一个token,如上图,现在尝试下使用响应中的refresh_token来刷新一下token看看
对/oauth2/token接口发起一个POST请求,请求参数为grant_type和refresh_token,还有客户端的相关认证

  1. grant_type:刷新token时固定值为refresh_token
  2. refresh_token:请求/oauth2/token接口响应数据中的refresh_token
    Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

另外,不要忘了basic auth的请求头
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet
接下来编写一个测试接口并添加@PreAuthorize(“hasAuthority(‘app’)”)注解,设置只有拥有app权限的人才能访问接口,如下

package com.example.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 测试接口
 *
 * @author vains
 */
@RestController
public class TestController {

    @GetMapping("/test01")
    @PreAuthorize("hasAuthority('app')")
    public String test01() {
        return "test01";
    }

}

然后携带token去请求这个测试接口
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet
这时我们会发现接口响应403,并且错误信息都在响应头中,而响应内容是空的。如下
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet
我们来看下框架中关于权限不足的默认实现,将提取出来的异常信息放入响应头中返回
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

响应的错误信息在请求头中是因为源码中提到的RFC 6750和oauth2.1协议规范中的The WWW-Authenticate Response Header Field规定了异常信息的位置
接下来就是403的问题,之前我们获取token的时候是通过授权码流程获取token,oauth2的授权实际上是依赖客户端的scope,用户在发起授权时是通过申请客户端scope的方式来获取授权,所以token中此时实际上只有我们申请的scope权限,我们断点看一下携带token请求时通过BearerTokenAuthenticationFilter解析token获取的认证信息。
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet
我们可以看到,通过token获取的权限只有scope的内容,并且有个前缀SCOPE_,这个前缀是在JwtGrantedAuthoritiesConverter类解析token时默认添加的,如下
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet
如果想要去除这个前缀则重写该类就行,详细内容请等待下一章扩展篇
按照这个规则将@PreAuthorize(“hasAuthority(‘app’)”)中的值app改为SCOPE_message.read,重启重新访问
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet
出现这个问题是因为重启后jws的配置发生了变化,无法正确解析token,重新调用一下刷新token的接口获取一个token就行
刷新token后访问接口,这时请求就正常了,没有响应403权限不足的提示了。
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

3. 客户端模式

该模式是为客户端准备的,客户端内部调用时可能会用到该模式
客户端模式的参数有四个,grant_type、scope、client_id和client_secret,客户端认证方式不是client_secret_post的客户端发起请求时只用携带grant_type参数即可,其它方式按照各自特点携带客户端的认证信息。
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

grant_type 在客户端模式下固定为client_credentials
client_id:客户端的id
client_secret: 客户端的秘钥
scope:本次请求授权的范围

拼接完scope参数请求如下示例
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

4. 授权码扩展流程PKCE(Proof Key for Code Exchange)

首先需要添加一个公共客户端并且设置proof key支持,为求方便直接修改AuthorizationConfig.java,之后重启服务,会添加一条适用pkce流程的客户端

/**
 * 配置客户端Repository
 *
 * @param jdbcTemplate    db 数据源信息
 * @param passwordEncoder 密码解析器
 * @return 基于数据库的repository
 */
@Bean
public RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate, PasswordEncoder passwordEncoder) {
    RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
            // 客户端id
            .clientId("messaging-client")
            // 客户端秘钥,使用密码解析器加密
            .clientSecret(passwordEncoder.encode("123456"))
            // 客户端认证方式,基于请求头的认证
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            // 配置资源服务器使用该客户端获取授权时支持的方式
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
            // 授权码模式回调地址,oauth2.1已改为精准匹配,不能只设置域名,并且屏蔽了localhost,本机使用127.0.0.1访问
            .redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
            .redirectUri("https://www.baidu.com")
            // 该客户端的授权范围,OPENID与PROFILE是IdToken的scope,获取授权时请求OPENID的scope时认证服务会返回IdToken
            .scope(OidcScopes.OPENID)
            .scope(OidcScopes.PROFILE)
            // 自定scope
            .scope("message.read")
            .scope("message.write")
            // 客户端设置,设置用户需要确认授权
            .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
            .build();

    // 基于db存储客户端,还有一个基于内存的实现 InMemoryRegisteredClientRepository
    JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);

    // 初始化客户端
    RegisteredClient repositoryByClientId = registeredClientRepository.findByClientId(registeredClient.getClientId());
    if (repositoryByClientId == null) {
        registeredClientRepository.save(registeredClient);
    }
    // 设备码授权客户端
    RegisteredClient deviceClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("device-message-client")
            // 公共客户端
            .clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
            // 设备码授权
            .authorizationGrantType(AuthorizationGrantType.DEVICE_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            // 自定scope
            .scope("message.read")
            .scope("message.write")
            .build();
    RegisteredClient byClientId = registeredClientRepository.findByClientId(deviceClient.getClientId());
    if (byClientId == null) {
        registeredClientRepository.save(deviceClient);
    }

    // PKCE客户端
    RegisteredClient pkceClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("pkce-message-client")
            // 公共客户端
            .clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
            // 设备码授权
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            // 授权码模式回调地址,oauth2.1已改为精准匹配,不能只设置域名,并且屏蔽了localhost,本机使用127.0.0.1访问
            .redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
            .clientSettings(ClientSettings.builder().requireProofKey(Boolean.TRUE).build())
            // 自定scope
            .scope("message.read")
            .scope("message.write")
            .build();
    RegisteredClient findPkceClient = registeredClientRepository.findByClientId(pkceClient.getClientId());
    if (findPkceClient == null) {
        registeredClientRepository.save(pkceClient);
    }
    return registeredClientRepository;
}

1. 生成Code Verifier和Code Challenge

在线生成网站
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet
生成示例
Code Verifier:0q9mMHEV-E_-8vxP2Aa93Y6ZKmXCan36YfAoLQViXvo
Code Challenge:kfis_wJYpmCAPO-Ap1Sc6GXyz_x2dhhMsm9FOA7eEWY

2. 拼接请求地址

http://127.0.0.1:8080/oauth2/authorize?response_type=code&client_id=pkce-message-client&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Flogin%2Foauth2%2Fcode%2Fmessaging-client-oidc&scope=message.read&code_challenge=kfis_wJYpmCAPO-Ap1Sc6GXyz_x2dhhMsm9FOA7eEWY&code_challenge_method=S256

参数说明

response_type: 固定值为code
client_id: 客户端id
redirect_uri:获取授权的回调地址
scope:请求授权的范围
code_challenge:在CodeVerifier的SHA256值基础上,再用BASE64URL编码

3. 重定向至登录页面

授权接口检测到尚未登录,重定向至登录页面
Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

4. 重定向至第2步指定的redirect_uri地址

Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet

5. 使用Postman模拟客户端发起请求获取token

Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试,Spring Authorization Server,Spring Security,Spring,spring,java,servlet
参数解释

grant_type: 跟授权码一样,固定为authorization_code
client_id:客户端id
redirect_uri:第2步中的回调地址
code_verifier:第1步中生成的code_verifier
code:授权接口重定向至回调地址时携带的参数code

总结

至此oauth2.1的所有流程基本都测试了一遍,设备码因为需要在原有基础上进行扩展,也留到下一章的扩展篇一块儿测试,在以后的文章会有设备码流程、登录添加图形验证码、自定义token生成和解析、自定义响应体和去除权限前缀等内容。文章来源地址https://www.toymoban.com/news/detail-678542.html

到了这里,关于Spring Authorization Server入门 (三) 集成流程说明、细节补充和各种方式获取token测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Spring Authorization Server入门 (十六) Spring Cloud Gateway对接认证服务

            之前虽然单独讲过Security Client和Resource Server的对接,但是都是基于Spring webmvc的,Gateway这种非阻塞式的网关是基于webflux的,对于集成Security相关内容略有不同,且涉及到代理其它微服务,所以会稍微比较麻烦些,今天就带大家来实现Gateway网关对接OAuth2认证服务。

    2024年02月10日
    浏览(45)
  • Spring Authorization Server入门 (十五) 分离授权确认与设备码校验页面

    2023-12-01修改:在session-data-redis(Github)分支中添加了基于 spring-session-data-redis 的实现,无需借助 nonceId 来保持认证状态,该分支已去除所有 nonceId 相关内容,需要注意的是 axios 在初始化时需要添加配置 withCredentials: true ,让请求携带cookie。当然一些响应json的处理还是使用下方的

    2024年02月14日
    浏览(26)
  • Spring Authorization Server入门 (二十) 实现二维码扫码登录

    打开网页,发起授权申请/未登录被重定向到登录页面 选择二维码登录,页面从后端请求二维码 页面渲染二维码图片,并轮询请求,获取二维码的状态 事先登录过APP的手机扫描二维码,然后APP请求服务器端的API接口,把用户认证信息传递到服务器中 后端收到APP的请求后更改

    2024年02月21日
    浏览(28)
  • 【Spring Authorization Server 系列】(一)入门篇,快速搭建一个授权服务器

    官方主页:https://spring.io/projects/spring-authorization-server Spring Authorization Server 是一个框架,提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。 它建立在 Spring Security 之上,为构建 OpenID Connect 1.0 Identity Providers 和 OAuth2 Authorization Server 产品提供安全、轻量级和可定制

    2024年02月16日
    浏览(37)
  • Spring Authorization Server入门 (一) 初识SpringAuthorizationServer和OAuth2.1协议

    经过近些年网络和设备的不断发展,之前的oauth2.0发布的授权协议标准已经远远不能满足现在的场景和需求,根据其安全最佳实践,在oauth2.0的基础上移除了一些不安全的授权方式,并且对扩展协议进行整合。该协议定义了一系列关于授权的开放网络标准,允许用户授权第三方

    2024年02月11日
    浏览(23)
  • Spring Authorization Server入门 (十二) 实现授权码模式使用前后端分离的登录页面

    2023-12-01修改:在session-data-redis(Github)分支中添加了基于 spring-session-data-redis 的实现,无需借助 nonceId 来保持认证状态,该分支已去除所有 nonceId 相关内容,需要注意的是 axios 在初始化时需要添加配置 withCredentials: true ,让请求携带cookie。当然一些响应json的处理还是使用下方的

    2024年02月13日
    浏览(29)
  • Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例

    有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.0.4 本系列Spring Security 版本 6.0.2 本系列Spring Authorization Server 版本 1.0.2 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo 在前几篇文档中,我们学习了 OAuth 2.0 协议,并使用 spring-security-oauth2-client 完成

    2024年02月12日
    浏览(29)
  • Spring Authorization Server入门 (八) Spring Boot引入Security OAuth2 Client对接认证服务

    在之前的文章中实现了一个认证服务,并且添加了一些自定义的内容,现在暂时没想到认证服务的新内容,本篇文章就先写一下客户端对接的吧,水一篇。 当用户通过客户端去访问一个受限的资源时,客户端会检测是否有登录信息,没有登录信息会重定向至认证服务器去请求

    2024年02月21日
    浏览(37)
  • Spring Authorization Server 授权服务器

    Spring Authorization Server 遵循Oauth2.1和OpenID Connect 1.0,它建立在 Spring Security 之上。 要求JDK11以上 使用Idea创建一个Maven的Spring Boot(笔者使用的是 spring boot 2.7 )项目 pom需要引入 Authorization Server的配置 完整的pom.xml文件如下: 使用 @Bean 和 @Configuration 创建配置,这是官方推荐的最小配

    2024年02月16日
    浏览(29)
  • Spring Security 源码解读:OAuth2 Authorization Server

    样例代码请参考:spring-security-oauth2.0-sample Spring Authorization Server刚发展不久,还没有springboot版本,而Resource Server有,但是两个底层很多不兼容,会重复引入不同版本的jar包。 另外,该 spring-security-oauth2-authorization-server 依赖支持OAuth2.1草案规范。 关于 OAuth2.1 草案介绍请参考

    2023年04月22日
    浏览(28)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包