![](/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.