我一直在搜索许多SO答案,Git问题等。我无法找到一种方法,仅使用Spring Security而不使用不推荐使用的"Spring Security OAuth"项目来撤销用户注销时的刷新令牌。
有没有一种方法可以自动管理此问题,而不是由我自己手动向IdP发出请求?
我想做的是在执行注销后,在RFC7009之后使用撤销的IdP端点撤销令牌,以避免出于上下文原因和出于安全原因使用此刷新令牌。
答案 0 :(得分:0)
在an issue in GitHub中介绍了RFC7009的当前支持以及Spring Security中的自动令牌撤销之后,我通过使用一个自定义LogoutHandler
实现了推荐的解决方案:
我在我的项目(实现LogoutHandler
)中创建了以下类:
CustomLogoutHandler.java
package com.test.demo.authorization;
import org.springframework.core.env.Environment;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Service
public class CustomLogoutHandler implements LogoutHandler {
private final Environment env;
private final OAuth2AuthorizedClientService authorizedClientService;
public CustomLogoutHandler(Environment env, OAuth2AuthorizedClientService authorizedClientService) {
this.env = env;
this.authorizedClientService = authorizedClientService;
}
@Override
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
String clientRegistrationId = ((OAuth2AuthenticationToken) authentication).getAuthorizedClientRegistrationId();
OAuth2AuthorizedClient authorizedClient = this.authorizedClientService.loadAuthorizedClient(clientRegistrationId, authentication.getName());
revokeRefreshToken(authorizedClient.getRefreshToken().getTokenValue());
}
private void revokeRefreshToken(String refreshToken) {
String revocationEndpoint = env.getProperty("spring.security.oauth2.client.registration.test.revocation-endpoint");
String clientId = env.getProperty("spring.security.oauth2.client.registration.test.client-id");
String clientSecret = env.getProperty("spring.security.oauth2.client.registration.test.client-secret");
LinkedMultiValueMap map = new LinkedMultiValueMap();
map.add("token_type_hint", "refresh_token");
map.add("token", refreshToken);
map.add("client_id", clientId);
map.add("client_secret", clientSecret);
WebClient revokeTokenWebClient = WebClient.builder()
.baseUrl(revocationEndpoint).build();
revokeTokenWebClient
.post()
.body(BodyInserters.fromMultipartData(map))
.retrieve()
.bodyToMono(String.class)
.block();
return;
}
}
之后,在我的WebSecurityConfigurerAdapter
中的configure方法中,我设置了以下内容:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/img/**", "/favicon.ico", "/logged-out", "/oauth/logout")
.permitAll()
.anyRequest()
.fullyAuthenticated()
.and()
.logout()
.addLogoutHandler(logoutHandler)
.logoutSuccessHandler(oidcLogoutSuccessHandler());
}
这样做,我已经实现了注销应用程序时自动撤销refresh_token
的功能。