mirror of https://github.com/halo-dev/halo
Refactor logout handler (#7470)
#### What type of PR is this? /kind cleanup /area core /milestone 2.21.x #### What this PR does / why we need it: This PR corrects location of LogoutHandler instead of in LogoutSuccessHandler. LogoutHanadler should be invoked before LogoutSuccessHandler. #### Does this PR introduce a user-facing change? ```release-note None ```pull/7475/head
parent
5c27a0484b
commit
ccdb97743b
|
@ -3,6 +3,7 @@ package run.halo.app.security;
|
||||||
import static run.halo.app.security.authentication.WebExchangeMatchers.ignoringMediaTypeAll;
|
import static run.halo.app.security.authentication.WebExchangeMatchers.ignoringMediaTypeAll;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
@ -19,8 +20,10 @@ import org.springframework.security.web.server.DefaultServerRedirectStrategy;
|
||||||
import org.springframework.security.web.server.ServerRedirectStrategy;
|
import org.springframework.security.web.server.ServerRedirectStrategy;
|
||||||
import org.springframework.security.web.server.WebFilterExchange;
|
import org.springframework.security.web.server.WebFilterExchange;
|
||||||
import org.springframework.security.web.server.authentication.logout.DelegatingServerLogoutHandler;
|
import org.springframework.security.web.server.authentication.logout.DelegatingServerLogoutHandler;
|
||||||
|
import org.springframework.security.web.server.authentication.logout.SecurityContextServerLogoutHandler;
|
||||||
import org.springframework.security.web.server.authentication.logout.ServerLogoutHandler;
|
import org.springframework.security.web.server.authentication.logout.ServerLogoutHandler;
|
||||||
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler;
|
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler;
|
||||||
|
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
|
||||||
import org.springframework.security.web.server.savedrequest.ServerRequestCache;
|
import org.springframework.security.web.server.savedrequest.ServerRequestCache;
|
||||||
import org.springframework.security.web.server.savedrequest.WebSessionServerRequestCache;
|
import org.springframework.security.web.server.savedrequest.WebSessionServerRequestCache;
|
||||||
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
|
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
|
||||||
|
@ -34,15 +37,12 @@ import run.halo.app.core.user.service.UserLoginOrLogoutProcessing;
|
||||||
import run.halo.app.core.user.service.UserService;
|
import run.halo.app.core.user.service.UserService;
|
||||||
import run.halo.app.infra.actuator.GlobalInfoService;
|
import run.halo.app.infra.actuator.GlobalInfoService;
|
||||||
import run.halo.app.security.authentication.SecurityConfigurer;
|
import run.halo.app.security.authentication.SecurityConfigurer;
|
||||||
import run.halo.app.security.authentication.rememberme.RememberMeServices;
|
|
||||||
import run.halo.app.theme.router.ModelConst;
|
import run.halo.app.theme.router.ModelConst;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Order(0)
|
@Order(0)
|
||||||
public class LogoutSecurityConfigurer implements SecurityConfigurer {
|
class LogoutSecurityConfigurer implements SecurityConfigurer {
|
||||||
|
|
||||||
private final RememberMeServices rememberMeServices;
|
|
||||||
|
|
||||||
private final ApplicationContext applicationContext;
|
private final ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@ -50,14 +50,29 @@ public class LogoutSecurityConfigurer implements SecurityConfigurer {
|
||||||
|
|
||||||
private final ServerRequestCache serverRequestCache = new HaloServerRequestCache();
|
private final ServerRequestCache serverRequestCache = new HaloServerRequestCache();
|
||||||
|
|
||||||
|
private final ServerSecurityContextRepository securityContextRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(ServerHttpSecurity http) {
|
public void configure(ServerHttpSecurity http) {
|
||||||
var serverLogoutHandlers = getLogoutHandlers();
|
http.logout(logout -> logout
|
||||||
http.logout(
|
.logoutHandler(getLogoutHandler())
|
||||||
logout -> logout.logoutSuccessHandler(new LogoutSuccessHandler(serverLogoutHandlers))
|
.logoutSuccessHandler(new LogoutSuccessHandler())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ServerLogoutHandler getLogoutHandler() {
|
||||||
|
var defaultLogoutHandler = new SecurityContextServerLogoutHandler();
|
||||||
|
defaultLogoutHandler.setSecurityContextRepository(securityContextRepository);
|
||||||
|
var logoutHandlers = new ArrayList<ServerLogoutHandler>();
|
||||||
|
logoutHandlers.add(defaultLogoutHandler);
|
||||||
|
applicationContext.getBeanProvider(ServerLogoutHandler.class)
|
||||||
|
.forEach(logoutHandlers::add);
|
||||||
|
if (logoutHandlers.size() == 1) {
|
||||||
|
return logoutHandlers.getFirst();
|
||||||
|
}
|
||||||
|
return new DelegatingServerLogoutHandler(logoutHandlers);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
RouterFunction<ServerResponse> logoutPage(
|
RouterFunction<ServerResponse> logoutPage(
|
||||||
UserService userService,
|
UserService userService,
|
||||||
|
@ -93,25 +108,17 @@ public class LogoutSecurityConfigurer implements SecurityConfigurer {
|
||||||
private class LogoutSuccessHandler implements ServerLogoutSuccessHandler {
|
private class LogoutSuccessHandler implements ServerLogoutSuccessHandler {
|
||||||
|
|
||||||
private final ServerLogoutSuccessHandler defaultHandler;
|
private final ServerLogoutSuccessHandler defaultHandler;
|
||||||
private final ServerLogoutHandler logoutHandler;
|
|
||||||
|
|
||||||
public LogoutSuccessHandler(ServerLogoutHandler... logoutHandlers) {
|
public LogoutSuccessHandler() {
|
||||||
var redirectHandler = new RequestCacheRedirectLogoutSuccessHandler();
|
var redirectHandler = new RequestCacheRedirectLogoutSuccessHandler();
|
||||||
redirectHandler.setRequestCache(serverRequestCache);
|
redirectHandler.setRequestCache(serverRequestCache);
|
||||||
this.defaultHandler = redirectHandler;
|
this.defaultHandler = redirectHandler;
|
||||||
if (logoutHandlers.length == 1) {
|
|
||||||
this.logoutHandler = logoutHandlers[0];
|
|
||||||
} else {
|
|
||||||
this.logoutHandler = new DelegatingServerLogoutHandler(logoutHandlers);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> onLogoutSuccess(WebFilterExchange exchange,
|
public Mono<Void> onLogoutSuccess(WebFilterExchange exchange,
|
||||||
Authentication authentication) {
|
Authentication authentication) {
|
||||||
return logoutHandler.logout(exchange, authentication)
|
return userLoginOrLogoutProcessing.logoutProcessing(authentication.getName())
|
||||||
.then(rememberMeServices.loginFail(exchange.getExchange()))
|
|
||||||
.then(userLoginOrLogoutProcessing.logoutProcessing(authentication.getName()))
|
|
||||||
.then(ignoringMediaTypeAll(MediaType.APPLICATION_JSON)
|
.then(ignoringMediaTypeAll(MediaType.APPLICATION_JSON)
|
||||||
.matches(exchange.getExchange())
|
.matches(exchange.getExchange())
|
||||||
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
|
.filter(ServerWebExchangeMatcher.MatchResult::isMatch)
|
||||||
|
@ -127,11 +134,6 @@ public class LogoutSecurityConfigurer implements SecurityConfigurer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServerLogoutHandler[] getLogoutHandlers() {
|
|
||||||
return applicationContext.getBeansOfType(ServerLogoutHandler.class).values()
|
|
||||||
.toArray(new ServerLogoutHandler[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class RequestCacheRedirectLogoutSuccessHandler
|
private static class RequestCacheRedirectLogoutSuccessHandler
|
||||||
implements ServerLogoutSuccessHandler {
|
implements ServerLogoutSuccessHandler {
|
||||||
|
|
||||||
|
|
|
@ -367,7 +367,7 @@ public class TokenBasedRememberMeServices implements ServerLogoutHandler, Rememb
|
||||||
log.debug("Logout of user {}", (authentication != null) ? authentication.getName()
|
log.debug("Logout of user {}", (authentication != null) ? authentication.getName()
|
||||||
: "Unknown");
|
: "Unknown");
|
||||||
}
|
}
|
||||||
return onLogout(exchange, authentication);
|
return loginFail(exchange.getExchange()).then(onLogout(exchange, authentication));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Mono<Void> onLogout(WebFilterExchange exchange, Authentication authentication) {
|
protected Mono<Void> onLogout(WebFilterExchange exchange, Authentication authentication) {
|
||||||
|
|
Loading…
Reference in New Issue