Spring Authorization Server 定制AccessToken

Spring Authorization Server

上一篇文章讲了如何扩展Spring Authorization Server,以便支持OAuth2.0协议版本中的Password授权码,你可以举一反三定义其他业务特定的授权码。在前面几篇文章中,获得access_token之后,我们并没有详细看这个JWT格式的token中包含哪些信息,这一篇将介绍它,并且会教你如何往token中插入自己的数据,满足业务需求。

1.Token定制器

Spring Authorization Server给我们留了一个OAuth2TokenCustomizer接口方便我们定制化,首先实现该接口并注册到Spring容器中:

java 复制代码
    @Bean
    public OAuth2TokenCustomizer<JwtEncodingContext> jwtTokenCustomizer() {
        return (context) -> {
            if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) {
                context.getClaims().claims((claims) -> {
                    // 从context中获取用户信息放到jwt的claims中
                    claims.put("user", context.getPrincipal().getPrincipal());
                    Set<String> roles = AuthorityUtils.authorityListToSet(context.getPrincipal().getAuthorities())
                            .stream()
                            .map(c -> c.replaceFirst("^ROLE_", ""))
                            .collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));
                    // 把用户角色放到claims中
                    claims.put("roles", roles);
                });
            }
        };
    }

2.Token生成器

接下来需要定义并注册一个TokenGenerator类型的bean:

java 复制代码
    @Bean
    OAuth2TokenGenerator<?> tokenGenerator(JWKSource<SecurityContext> jwkSource, OAuth2TokenCustomizer<JwtEncodingContext> tokenCustomizer) {
        JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource));
        // 设置OAuth2TokenCustomizer
        jwtGenerator.setJwtCustomizer(tokenCustomizer);
        OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
        OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
        return new DelegatingOAuth2TokenGenerator(
                jwtGenerator, accessTokenGenerator, refreshTokenGenerator);
    }

3.测试验证

完成上述两步之后,便可以启动AuthServer,通过上一篇文章中扩展的Password授权码直接获取AccessToken:

bash 复制代码
curl -XPOST -u 'hello:123456' 'http://127.0.0.1:8000/oauth2/token?client_id=hello&grant_type=password&username=admin&password=123456'

得到access_token后,可以复制到jwt.io这个站点去解析,可以看到结果类似如下:

json 复制代码
{
  "sub": "admin",
  "aud": "hello",
  "nbf": 1710255228,
  "scope": [
    "openid",
    "profile"
  ],
  "roles": [],
  "iss": "http://127.0.0.1:8000",
  "exp": 1710341628,
  "iat": 1710255228,
  "user": "admin",
  "jti": "e98fdc73-cdf5-4c2e-840a-27a0dd286f11"
}

轻松拿下~

相关推荐
tan180°40 分钟前
Linux进程信号处理(26)
linux·c++·vscode·后端·信号处理
一只码代码的章鱼1 小时前
Spring的 @Validate注解详细分析
前端·spring boot·算法
有梦想的攻城狮1 小时前
spring中的@MapperScan注解详解
java·后端·spring·mapperscan
柚个朵朵2 小时前
Spring的Validation,这是一套基于注解的权限校验框架
java·后端·spring
程序员小杰@2 小时前
【MCP教程系列】SpringBoot 搭建基于 Spring AI 的 SSE 模式 MCP 服务
人工智能·spring boot·spring
程序员buddha3 小时前
Spring & Spring Boot 常用注解整理
java·spring boot·spring
Asus.Blogs3 小时前
为什么go语言中返回的指针类型,不需要用*取值(解引用),就可以直接赋值呢?
开发语言·后端·golang
C_V_Better3 小时前
Java Spring Boot 控制器中处理用户数据详解
java·开发语言·spring boot·后端·spring
胡子洲3 小时前
Spring Boot 应用中实现基本的 SSE 功能
java·spring boot·后端
非著名架构师3 小时前
SpringBoot整合MQTT实战:基于EMQX构建高可靠物联网通信,从零到一实现设备云端双向对话
spring boot·mqtt·emqx