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"
}
轻松拿下~