【spring authorization server系列教程】(一)入门系列,spring authorization server简介。快速构建一个授权服务器(基于最新版本0.3.0)

系列文章目录

【spring authorization server系列教程】(一)入门系列,快速构建一个授权服务器


文章目录


前言

spring authorization server是spring团队最新的认证授权服务器,之前的oauth2后面会逐步弃用。不过到现在发文的时候,我看到官网已经把之前oauth2仓库废弃了。
现在spring authorization server已经到生产就绪阶段了,不过目前项目还没有完全到生产可用阶段。
springsecurityoauth迁移到新的授权服务器指南 https://github.com/spring-projects/spring-security/wiki/OAuth-2.0-Migration-Guide
spring authorization server官方demo https://github.com/spring-projects/spring-authorization-server
上篇文章也有集成jdbc例子https://blog.csdn.net/qq_35270805/article/details/123125144

一、目前已实现的功能

Spring Authorization Server 支持以下特性:

授权方式

  • 授权码

     用户同意
    
  • 客户凭证

  • 刷新令牌

OAuth 2.1 授权框架(草案)

  • 授权码授予

  • 客户凭证授予

  • 刷新令牌授予

OpenID Connect Core 1.0(规范)

  • 授权码流程

令牌格式

  • 自包含 (JWT)

  • 参考(不透明)

  • JSON Web 令牌 (JWT) ( RFC 7519 )

  • JSON Web 签名 (JWS) ( RFC 7515 )

客户端认证

  • client_secret_basic

  • client_secret_post

  • client_secret_jwt

  • private_key_jwt

  • none(公众客户)

  • OAuth 2.1 授权框架(客户端身份验证)

  • 用于 OAuth 2.0 客户端身份验证的 JSON Web 令牌 (JWT) 配置文件 ( RFC 7523 )

  • OAuth 公共客户端 (PKCE) 的代码交换证明密钥 ( RFC 7636 )

协议端点

  • OAuth2 授权端点

  • OAuth2 令牌端点

  • OAuth2 令牌自省端点

  • OAuth2 令牌撤销端点

  • OAuth2 授权服务器元数据端点

  • JWK 设置端点

  • OpenID Connect 1.0 提供者配置端点

  • OpenID Connect 1.0 用户信息端点

  • OpenID Connect 1.0 客户端注册端点

  • OAuth 2.1 授权框架(草案)

    • 授权端点

    • 令牌端点

  • OAuth 2.0 令牌自省 ( RFC 7662 )

  • OAuth 2.0 令牌撤销 ( RFC 7009 )

  • OAuth 2.0 授权服务器元数据 ( RFC 8414 )

  • JSON 网络密钥 (JWK) ( RFC 7517 )

  • OpenID Connect Discovery 1.0(规范)

    • 提供者配置端点
  • OpenID Connect Core 1.0(规范)

    • 用户信息端点
  • OpenID Connect 动态客户端注册 1.0(规范)

    • 客户注册端点

    • 客户端配置端点

从上面官方表可以看出,协议是最新的oauth2.1协议。因为协议变更了,所以最新版本也就没有了密码模式授权

二、入门,一步一步快速开始构建一个简单的认证服务器

1.创建springboot项目并引入依赖

Spring Authorization Server 可以在您已经使用Spring Security的任何地方使用。

开始使用 Spring Authorization Server 的最简单方法是创建基于Spring Boot的应用程序。您可以使用start.spring.io生成基本项目或使用默认授权服务器示例作为指导。然后将 Spring Authorization Server 添加为依赖项,如下例所示:

		<!--spring-authorization-server依赖-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-authorization-server</artifactId>
            <version>0.3.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

截至目前为止最新版本为0.3.0

2.配置SecurityConfig

代码如下:

**
 * @author resthx
 * @date 9:21 2022/6/7
 */
@Configuration
public class SecurityConfig {

    /**
     * 端点的 Spring Security 过滤器链
     * @param http
     * @return
     * @throws Exception
     */
    @Bean
    @Order
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
            throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
        //未通过身份验证时重定向到登录页面授权端点
        http.exceptionHandling((exceptions) -> exceptions
                        .authenticationEntryPoint(
                                new LoginUrlAuthenticationEntryPoint("/login"))
                );

        return http.build();
    }

    /**
     * 用于身份验证的 Spring Security 过滤器链
     * @param http
     * @return
     * @throws Exception
     */
    @Bean
    @Order
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
            throws Exception {
        http
                .authorizeHttpRequests((authorize) -> authorize
                        .anyRequest().authenticated()
                )
                //表单登录处理从授权服务器过滤器链
                .formLogin(Customizer.withDefaults());

        return http.build();
    }

    /**
     * 配置UserDetails
     * @return
     */
    @Bean
    public UserDetailsService userDetailsService() {
        //这里用固定的用户,后续改成从数据库查询
        UserDetails userDetails = User.withDefaultPasswordEncoder()
                .username("admin")
                .password("111111")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(userDetails);
    }

    /**
     * 返回注册客户端资源,注意这里采用的是内存模式,后续可以改成jdbc模式。RegisteredClientRepository用于管理客户端的实例。
     * @return
     */
    @Bean
    public RegisteredClientRepository registeredClientRepository() {
        RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
                .clientId("messaging-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/login/oauth2/code/messaging-client-oidc")
                .redirectUri("http://www.baidu.com")
                .scope(OidcScopes.OPENID)
                .scope("message.read")
                .scope("message.write")
                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
                .build();

        return new InMemoryRegisteredClientRepository(registeredClient);
    }

    /**
     * 生成jwk资源,com.nimbusds.jose.jwk.source.JWKSource用于签署访问令牌的实例。
     * @return
     */
    @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);
    }

    /**
     * 生成密钥对,启动时生成的带有密钥的实例java.security.KeyPair用于创建JWKSource上述内容
     * @return
     */
    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;
    }

    /**
     * ProviderSettings配置 Spring Authorization Server的实例
     * @return
     */
    @Bean
    public ProviderSettings providerSettings() {
        return ProviderSettings.builder().build();
    }

}

3.配置application.yml

server:
  port: 9600

到这里就配置完成了。。。。。。。。。。。。。。。。。。。。。。。。。。。初始配置简单的一个配置就够了。下面开始进行测试

这里我们只测试授权码模式。其他模式这里就不测试了

浏览器访问http://127.0.0.1:9600/oauth2/authorize?client_id=messaging-client&response_type=code&scope=message.read&redirect_uri=http://www.baidu.com
会跳转到登录页面
在这里插入图片描述
输入配置中的账户名密码,然后就跳转到认证页面了
在这里插入图片描述
勾选上message.read,然后点击提交
在这里插入图片描述
就跳转到百度然后后面带上了code
然后再用postman请求,像我这样配置
在这里插入图片描述
在这里插入图片描述
code替换成跳转路径后面那个
发送请求
在这里插入图片描述
这时候服务器就饭后了token

总结

以上就是今天要讲的内容,本文介绍了spring authorization server,还有他的简单上手demo。后面我会出这系列后续教程,,如何定制页面,更多的相关配置介绍,喜欢可以收藏一下,后续更新

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦


版权声明:本文为m0_67403272原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。