![](/img/trans.png)
[英]OAuth2 refresh_token logic implementation in spring-security-oauth2
[英]How to access the “id_token” and “refresh_token” when using spring-security-oauth2 client with OpenID Connect provider?
我已成功将Spring Security OAuth2与我的Open ID Connect提供程序(Forgerock OpenAM)集成。 我可以看到正在检索的访问令牌。 如何从/token
端点访问作为响应一部分的id_token
和refresh_token
?
最后找出答案和发布,以防它对有相同问题的人有用。 会话通过Spring Security OAuth2进行Authentication
,会有一个Authentication
对象设置。 它需要转换为OAuth2Authentication
的实例。 该对象具有令牌。
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof OAuth2Authentication) {
Object details = auth.getDetails();
OAuth2AccessToken token = oauth2Ctx.getAccessToken();
if (token != null && !token.isExpired()) {
// Do Stuff
}
一个替代方法的完整示例(使用Spring Boot并禁用其自动配置的一部分)。
application.properties:
security.oauth2.client.client-id=client-id
security.oauth2.client.client-secret=client-secret
security.oauth2.client.access-token-uri=http://my-oidc-provider/auth/oauth2/token
security.oauth2.client.user-authorization-uri=http://my-oidc-provider/auth/oauth2/authorize
security.oauth2.resource.token-info-uri=http://my-oidc-provider/auth/oauth2/check_token
security.oauth2.client.scope=openid,email,profile
security.oauth2.resource.jwk.key-set-uri=http://my-oidc-provider/auth/oidc/jwks
/**
* Extending the AuthorizationServerEndpointsConfiguration disables the Spring
* Boot ResourceServerTokenServicesConfiguration.
*/
@Configuration
@EnableOAuth2Sso
public class OAuth2Config extends AuthorizationServerEndpointsConfiguration {
@Value("${security.oauth2.resource.jwk.key-set-uri}")
private String keySetUri;
@Value("${security.oauth2.resource.token-info-uri}")
private String checkTokenEndpointUrl;
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Value("${security.oauth2.client.client-secret}")
private String clientSecret;
@Bean
public RemoteTokenServices resourceServerTokenServices() {
RemoteTokenServices tokenService = new RemoteTokenServices();
DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
accessTokenConverter.setUserTokenConverter(new CustomIdTokenConverter(keySetUri));
tokenService.setAccessTokenConverter(accessTokenConverter);
tokenService.setCheckTokenEndpointUrl(checkTokenEndpointUrl);
tokenService.setClientId(clientId);
tokenService.setClientSecret(clientSecret);
return tokenService;
}
@Bean
public ClientDetailsService clientDetailsService() {
return new InMemoryClientDetailsService();
}
@Bean
public UserInfoRestTemplateFactory userInfoRestTemplateFactory(
ObjectProvider<List<UserInfoRestTemplateCustomizer>> customizers,
ObjectProvider<OAuth2ProtectedResourceDetails> details,
ObjectProvider<OAuth2ClientContext> oauth2ClientContext) {
return new DefaultUserInfoRestTemplateFactory(customizers, details,
oauth2ClientContext);
}
}
public class CustomIdTokenConverter extends DefaultUserAuthenticationConverter {
private final JwkTokenStore jwkTokenStore;
public CustomIdTokenConverter(String keySetUri) {
this.jwkTokenStore = new JwkTokenStore(keySetUri);
}
@Override
public Authentication extractAuthentication(Map<String, ?> map) {
String idToken = (String) map.get("id_token");
OAuth2AccessToken token = jwkTokenStore.readAccessToken(idToken);
Map<String, Object> claims = token.getAdditionalInformation();
OAuth2RefreshToken refreshToken = token.getRefreshToken();
String principal = (String) claims.get("sub");
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_USER");
return new CustomAuthenticationData(principal, claims, authorities);
}
}
public class CustomAuthenticationData extends UsernamePasswordAuthenticationToken {
private final Map<String, Object> attributes;
public CustomAuthenticationData(String username, Map<String, Object> attributes, Collection<? extends GrantedAuthority> authorities) {
super(username, "N/A", authorities);
this.attributes = attributes;
}
public Map<String, Object> getAttributes() {
return attributes;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.