前言

  • Spring Authorization Server 是 Spring 团队最新开发适配 OAuth 协定的受权服务器我的项目,旨在代替原有的 Spring Security OAuth
  • 通过半年的开发和孵化,目前曾经公布了 0.1.0 版本,初步反对受权码、客户端、刷新、登记等 OAuth 协定
  • 本文环境基于 Spring Boot 2.4.2 && authorization-server 0.1.0

Server 搭建

1. maven 依赖

<!--oauth2 server--><dependency>  <groupId>org.springframework.security.experimental</groupId>  <artifactId>spring-security-oauth2-authorization-server</artifactId>  <version>0.1.0</version></dependency><!--security dependency--><dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-security</artifactId></dependency>

2. 初始化配置

  • 因为官网还未提供对应的 Spring Boot Starter 自动化配置,须要本人配置相干的 @Bean
  • 本配置基于 Spring Boot 2.4.2 请知悉
@Configuration@EnableWebSecurity@Import(OAuth2AuthorizationServerConfiguration.class)public class AuthServerConfiguration {    //  定义 spring security 拦击链规定    @Bean    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {        http                .authorizeRequests(authorizeRequests ->                        authorizeRequests.anyRequest().authenticated()                )                .formLogin(withDefaults());        return http.build();    }  // 创立默认登录用户 lengleng / 123456    @Bean    public UserDetailsService userDetailsService() {        UserDetails userDetails = User.builder()                .username("lengleng")                .password("{noop}123456")                .authorities("ROLE_USER")                .build();        return new InMemoryUserDetailsManager(userDetails);    }  // 创立默认的bean 登录客户端,基于 受权码、 刷新令牌的能力    @Bean    public RegisteredClientRepository registeredClientRepository() {        RegisteredClient client = RegisteredClient.withId("pig")                .clientId("pig")                .clientSecret("pig")                .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC)                .authorizationGrantTypes(authorizationGrantTypes -> {                    authorizationGrantTypes.add(AuthorizationGrantType.AUTHORIZATION_CODE);                    authorizationGrantTypes.add(AuthorizationGrantType.REFRESH_TOKEN);                })                .redirectUri("https://pig4cloud.com")                .build();        return new InMemoryRegisteredClientRepository(client);    }  // 指定token 生成的加解密密钥    @Bean    @SneakyThrows    public JWKSource<SecurityContext> jwkSource() {        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");        keyPairGenerator.initialize(2048);        KeyPair keyPair = keyPairGenerator.generateKeyPair();        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();        // @formatter:off        RSAKey rsaKey= new RSAKey.Builder(publicKey)                .privateKey(privateKey)                .keyID(UUID.randomUUID().toString())                .build();        JWKSet jwkSet = new JWKSet(rsaKey);        return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);    }}

测试

受权码认证

curl --location --request GET 'http://localhost:3000/oauth2/authorize?client_id=pig&client_secret=pig&response_type=code&redirect_uri=https://pig4cloud.com'

获取令牌

curl --location --request POST 'http://localhost:3000/oauth2/token' \--header 'Authorization: Basic cGlnOnBpZw==' \--header 'Content-Type: application/x-www-form-urlencoded' \--data-urlencode 'grant_type=authorization_code' \--data-urlencode 'code={code}' \--data-urlencode 'redirect_uri=https://pig4cloud.com'

刷新令牌

curl --location --request POST 'http://localhost:3000/oauth2/token' \--header 'Authorization: Basic cGlnOnBpZw==' \--header 'Content-Type: application/x-www-form-urlencoded' \--data-urlencode 'grant_type=refresh_token' \--data-urlencode 'refresh_token={refresh_token}' \

撤销令牌

  • 通过 access_token
curl --location --request POST 'http://localhost:3000/oauth2/revoke' \--header 'Authorization: Basic cGlnOnBpZw==' \--header 'Content-Type: application/x-www-form-urlencoded' \--data-urlencode 'token={access_token}' \--data-urlencode 'token_type_hint=access_token'
  • 通过 refresh_token
curl --location --request POST 'http://localhost:3000/oauth2/revoke' \--header 'Authorization: Basic cGlnOnBpZw==' \--header 'Content-Type: application/x-www-form-urlencoded' \--data-urlencode 'token={refresh_token}' \--data-urlencode 'token_type_hint=refresh_token'

内容扩大 | Token 个性化

  • RegisteredClient 反对个性化 token 设置的入参
RegisteredClient..tokenSettings()
  • 默认配置如下, 包含令牌有效期,刷新令牌管制等
    protected static Map<String, Object> defaultSettings() {        Map<String, Object> settings = new HashMap<>();        settings.put(ACCESS_TOKEN_TIME_TO_LIVE, Duration.ofMinutes(5));        settings.put(REUSE_REFRESH_TOKENS, true);        settings.put(REFRESH_TOKEN_TIME_TO_LIVE, Duration.ofMinutes(60));        return settings;    }

总结

  • 本节源码: https://github.com/lltx/auth-server-demo
  • 因为官网临时未欠缺相干的文档,所有的端点入参等须要参考 The OAuth 2.0 Authorization Framework

>>> 源码 https://gitee.com/log4j/pig,欢送署名转载 <<<