Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例

这篇具有很好参考价值的文章主要介绍了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

1. 前言

在前几篇文档中,我们学习了OAuth 2.0协议,并使用spring-security-oauth2-client完成了基于授权码模式的第三方平台登录功能。

OAuth 2.0中的四大角色,Spring Security原生框架已经帮我们实现了资源所有者、客户端、资源服务器,那么Spring是否提供了授权服务器的实现呢?

2. Spring Security OAuth

GitHub地址

2.1 简介

OAuth 1.0 时代,Spring组织已经开始开发基于Spring SecurityOAuth的支持,该框架就是Spring Security OAuth。其实现了大部分的OAuth规范,并提供了资源服务器、客户端和授权服务器

2.2 停止维护

2018年1月Spring 官方发布了一个将会停更Spring Security OAuth的通知,并开始在 Spring Security 5.0中构建下一代 0Auth2.0支持。

2019年11月Spring Security 0Auth客户端、资源服务器的功能大部分已迁移到Spring Security 5中,在5.3版本中完成了迁移工作,并添加了许多新功能,比如对OpenID Connect 1.0的支持。

Spring Security源码oauth2模块中可以看到相关体现:

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security

同时还宣布不再支持授权服务器,因为Spring 觉得授权服务器更像是一个产品,而Spring Security作为框架,并不适合做这件事情,而且已经有大量商业和开源并且成熟的授权服务器

2022年5月31日Spring Security OAuth正式归档。

3. Spring Authorization Server

GitHub地址

Spring Security OAuth的停止维护,以及Spring Security不再提供授权服务器这件事,在社区一石激起千层浪,引起很多人的反对,经过Spring社区的努力,Spring决定在2020年4月开始启动新的授权服务器项目。

3.1 简介

Spring Authorization Server是一个授权服务器框架,提供 OAuth 2.1 和 OpenID Connect 1.0 规范及其他相关规范的实现。它建立在 Spring Security 之上,为构建开发标准的授权服务器产品提供了一个安全、轻量级和可定制的基础。

注意: 是基于OAuth 2.1而不是2.0!!!目前最新版本为1.0.2,早前已经成为spring-projects下的正式项目,表明已经生产可用!!!

3.2 功能特性

授权模式支持:

  • 授权码模式
  • 客户端模式
  • 刷新令牌模式

令牌格式支持:

  • JWT
  • JWS

客户端认证方式支持:

  • client_secret_basic:基于Basic消息头认证
  • client_secret_postPOST请求进行认证
  • private_key_jwt: 基于JWT 进行认证,请求方使用私钥对JWT签名,授权服务器使用对应公钥进行验签认证
  • client_secret_jwt:基于JWT 进行认证,对JWT使用客户端密码+签名算法 签名
  • none (public clients):公共客户端

协议端点支持:

  • OAuth2 Authorization Endpoint:申请授权端点,默认为/oauth2/authorize
  • OAuth2 Token Endpoint:获取访问令牌端点,默认为/oauth2/token
  • OAuth2 Token Introspection Endpoint:令牌自省端点,默认为/oauth2/introspect
  • OAuth2 Token Revocation Endpoint:令牌撤销端点,默认为/oauth2/revoke
  • OAuth2 Authorization Server Metadata Endpoint:获取授权服务器元信息的端点,默认为/.well-known/oauth-authorization-server
  • JWK Set EndpointJWK信息端点,默认为/oauth2/jwks
  • OpenID Connect 1.0 Provider Configuration Endpoint:查询提供者配置端点,默认为/.well-known/openid-configuration
  • OpenID Connect 1.0 UserInfo Endpoint:用户信息端点,默认为/userinfo
  • OpenID Connect 1.0 Client Registration Endpoint:客户端注册端点,默认为/connect/registe

4. 案例演示

Spring Authorization Server基于 OAuth 2.1 和 OpenID Connect 1.0 规范,OAuth 2.12.0最大的区别就是删除了密码和简化模式。

4.1 环境搭建

创建一个Spring Boot基础工程,引入Spring授权服务器依赖:

        <!--Spring 授权服务器-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-authorization-server</artifactId>
            <version>1.0.2</version>
        </dependency>

4.2 配置类

添加SpringSecurity配置类,授权服务器是基于Spring Security开发的,本身也需要认证授权功能。

@Configuration(proxyBeanMethods = false)
public class SpringSecurityConfig {

    /**
     * Spring Security SecurityFilterChain 认证配置
     */
    @Bean
    @Order(2)
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
            throws Exception {
        http.authorizeHttpRequests((authorize) -> authorize
                        .anyRequest().authenticated()
                )
                .formLogin(Customizer.withDefaults());
        return http.build();
    }

    /**
     * 内存存储用户
     */
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails userDetails = User.withDefaultPasswordEncoder()
                .username("user")
                .password("123456")
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(userDetails);
    }
}

添加授权服务器配置类:

@Configuration(proxyBeanMethods = false)
public class SpringAuthServerConfig {

    /**
     * 授权服务器 SecurityFilterChain
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
            throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
        http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
                .oidc(Customizer.withDefaults());    // Enable OpenID Connect 1.0
        http
                // Redirect to the login page when not authenticated from the
                // authorization endpoint
                .exceptionHandling((exceptions) -> exceptions
                        .authenticationEntryPoint(
                                new LoginUrlAuthenticationEntryPoint("/login"))
                )
                // Accept access tokens for User Info and/or Client Registration
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
        return http.build();
    }

    /**
     * 客户端配置,基于内存
     */
    @Bean
    public RegisteredClientRepository registeredClientRepository() {
        // http://localhost:8080/oauth2/authorize?client_id=client&scope=user_info&state=123456&response_type=code&redirect_uri=http://127.0.0.1:8080/authorized
        RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
                .clientId("client")
                .clientSecret("{noop}secret")
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                .redirectUri("http://127.0.0.1:8080/callback")
                .scope("user_info")
                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
                .build();
        return new InMemoryRegisteredClientRepository(registeredClient);
    }


    /**
     * 解码签名访问令牌
     */
    @Bean
    public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
        return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
    }

    /**
     * 配置Spring授权服务器
     */
    @Bean
    public AuthorizationServerSettings authorizationServerSettings() {
        return AuthorizationServerSettings.builder().build();
    }
    
    /**
     * 访问令牌签名
     */
    @Bean
    public JWKSource<SecurityContext> jwkSource() {
        KeyPair keyPair = generateRsaKey();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAKey rsaKey = new RSAKey.Builder(publicKey)
                .privateKey(privateKey)
                .keyID(UUID.randomUUID().toString())
                .build();
        JWKSet jwkSet = new JWKSet(rsaKey);
        return new ImmutableJWKSet<>(jwkSet);
    }

    /**
     * 其 key 在启动时生成,用于创建上述 JWKSource
     */
    private static KeyPair generateRsaKey() {
        KeyPair keyPair;
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            keyPair = keyPairGenerator.generateKeyPair();
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
        return keyPair;
    }
}

4.3 授权码模式

浏览器地址栏访问申请授权码端点:

http://localhost:8080/oauth2/authorize?
client_id=client&
scope=user_info&
state=123456&
response_type=code&
redirect_uri=http://127.0.0.1:8080/callback

参数说明:

参数 说明 是否必填
client_id 客户端ID YES
response_type 响应模式,固定为code (授权码) YES
redirect_uri 回调地址,当授权码申请成功后l浏览器会重定向到此地址,并在后边带上code参数(授权码) YES
scope 用来限制客户端的访问范围(权限),如果为空的话,那么会返回客户端拥有全部的访问范围 NO
state 可以取随机值, 用于防止CSRF攻击 NO

之后会调转到登录接口,输入用户名密码:

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security
登录成功后跳转到授权页面,是否允许这个客户端访问你的资源,选择允许访问的范围,点击Submit Consent提交授权:

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security
之后浏览器会重定向到回调地址,并携带授权码参数:

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security
重定向URL如下所示:

http://127.0.0.1:8080/callback?
code=5rZRbGqLbqWxj1aeLP9otKce0XE_CfH4&
state=123456

接着使用授权码获取访问令牌端,需要Post请求,这里使用Postman,访问地址为http://localhost:8080/oauth2/token,首先需要传入客户端的ID及密码,可以采用Basic认证方式,并将其拼接成用户名:密码格式,中间是一个冒号,再用Base64编码,然后在请求头中附加 Authorization:Basic xxx。这里可以使用Postman选择Basic Auth,然后输入客户端ID及密码。

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security
添加请求参数,发送请求,可以看到成功返回了访问令牌、刷新令牌等信息:

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security

请求参数说明:

参数 说明
code 授权码,就是刚刚获取的授权码,注意:授权码只使用一次就无效了,需要重新申请
grant_type 授权类型,填写authorization_code,表示授权码模式
redirect_uri 申请授权码时的跳转url,一定要和申请授权码时用的redirect_uri一致。

当再次点击时,会报错,说明code只能使用一次:

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security

4.4 客户端模式

客户端模式,可以直接通过客户端认证返回访问令牌,授权类型为client_credentials,访问端点为:

http://localhost:8080/oauth2/token?grant_type=client_credentials

首先设置Basic认证参数:

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security

发送请求返回令牌:

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security

4.5 刷新令牌模式

访问令牌的有效期一般较短,这样可以保证在发生访问令牌泄露时,不至于造成太坏的影响,但是因为有限期太短,过期之后,需要重新授权获取令牌,这种方式不太友好。

所以在下发访问令牌的同时下发一个有效期较长的刷新令牌,访问令牌失效时,可以利用刷新令牌去授权服务器换取新的访问令牌。

首先同上设置Basic认证参数,然后访问/oauth2/token

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security
请求参数说明:

参数 说明
refresh_token 刷新令牌
grant_type 授权类型,填写refresh_token,表示刷新令牌模式

响应结果如下:

Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例,Spring Security 6.x,spring,spring boot,spring security文章来源地址https://www.toymoban.com/news/detail-520502.html

到了这里,关于Spring Security 6.x 系列【28】授权服务器篇之Spring Authorization Server 1.0 入门案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Spring Security 自定义授权服务器实践

    相关文章: OAuth2的定义和运行流程 Spring Security OAuth实现Gitee快捷登录 Spring Security OAuth实现GitHub快捷登录 Spring Security的过滤器链机制 Spring Security OAuth Client配置加载源码分析 Spring Security内置过滤器详解 为什么加载了两个OAuth2AuthorizationRequestRedirectFilter分析 在之前我们已经对接

    2024年02月02日
    浏览(52)
  • 搭建spring security oauth2认证授权服务器

    下面是在spring security项目的基础上搭建spring security oauth2认证授权服务器 spring security oauth2认证授权服务器主要需要以下依赖 Spring Security对OAuth2默认可访问端点 ​/oauth/authorize​ ​​:申请授权码code,涉及类​ ​AuthorizationEndpoint​ ​ ​/oauth/token​ ​​:获取令牌token,涉及类​

    2024年01月21日
    浏览(57)
  • Spring Security 6.x 系列【72】授权篇之角色分层

    有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列Spring Security 版本 6.1.0 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo

    2024年01月23日
    浏览(43)
  • Spring Security 6.x 系列【51】授权篇之动态权限规则

    有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列Spring Security 版本 6.1.0 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo 在开始阅读本篇文档前,您需要了解以下文档的相关知识: Spring Security 6.x 系列【16】授权篇之访问控制 Spring Securi

    2024年02月07日
    浏览(61)
  • 【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日
    浏览(52)
  • Spring Security 6.x 系列【45】微服务篇之搭建统一认证服务

    有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.0.4 本系列Spring Security 版本 6.0.2 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo

    2024年02月09日
    浏览(46)
  • 【spring authorization server系列教程】(一)入门系列,spring authorization server简介。快速构建一个授权服务器(基于最新版本0.3.0)

    【spring authorization server系列教程】(一)入门系列,快速构建一个授权服务器 spring authorization server是spring团队最新的认证授权服务器,之前的oauth2后面会逐步弃用。不过到现在发文的时候,我看到官网已经把之前oauth2仓库废弃了。 现在spring authorization server已经到生产就绪阶段了

    2024年02月05日
    浏览(55)
  • Spring Security 自定义资源服务器实践

    相关文章: OAuth2的定义和运行流程 Spring Security OAuth实现Gitee快捷登录 Spring Security OAuth实现GitHub快捷登录 Spring Security的过滤器链机制 Spring Security OAuth Client配置加载源码分析 Spring Security内置过滤器详解 为什么加载了两个OAuth2AuthorizationRequestRedirectFilter分析 Spring Security 自定义授

    2024年01月22日
    浏览(40)
  • Spring Security 6.0系列【8】认证篇之注销登录

    有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.0.4 本系列Spring Security 版本 6.0.2 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo

    2023年04月08日
    浏览(43)
  • Spring Security OAuth 2.0 资源服务器— JWT

    目录 一、JWT的最小依赖 二、JWT的最基本配置 1、指定授权服务器 2、初始预期(Startup Expectations) 3、运行时预期(Runtime Expectations) 三、JWT认证是如何工作的 四、直接指定授权服务器 JWK Set Uri 五、提供 audiences 六、覆盖或取代启动自动配置 1、使用jwkSetUri() 2、使用decoder()

    2024年02月05日
    浏览(62)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包