mirror of https://github.com/halo-dev/halo
Use AuthenticationWebFilter for remember-me mechanism (#6298)
#### What type of PR is this? /kind cleanup /area core /milestone 2.18.x #### What this PR does / why we need it: This PR simplifies RememberMeAuthenticationFilter by reusing AuthenticationWebFilter. #### Does this PR introduce a user-facing change? ```release-note None ```pull/6265/head^2
parent
9cdd8a5301
commit
45d0a475b5
|
@ -1,36 +0,0 @@
|
||||||
package run.halo.app.security.authentication.rememberme;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.lang.NonNull;
|
|
||||||
import org.springframework.security.core.AuthenticationException;
|
|
||||||
import org.springframework.security.core.context.SecurityContextImpl;
|
|
||||||
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
|
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
|
||||||
import org.springframework.web.server.WebFilter;
|
|
||||||
import org.springframework.web.server.WebFilterChain;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class RememberMeAuthenticationFilter implements WebFilter {
|
|
||||||
private final ServerSecurityContextRepository securityContextRepository;
|
|
||||||
private final RememberMeServices rememberMeServices;
|
|
||||||
private final RememberMeAuthenticationManager rememberMeAuthenticationManager;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NonNull
|
|
||||||
public Mono<Void> filter(@NonNull ServerWebExchange exchange, @NonNull WebFilterChain chain) {
|
|
||||||
return securityContextRepository.load(exchange)
|
|
||||||
.switchIfEmpty(Mono.defer(() -> rememberMeServices.autoLogin(exchange)
|
|
||||||
.flatMap(rememberMeAuthenticationManager::authenticate)
|
|
||||||
.flatMap(authentication -> {
|
|
||||||
var securityContext = new SecurityContextImpl(authentication);
|
|
||||||
return securityContextRepository.save(exchange, securityContext);
|
|
||||||
})
|
|
||||||
.onErrorResume(AuthenticationException.class,
|
|
||||||
e -> rememberMeServices.loginFail(exchange)
|
|
||||||
)
|
|
||||||
.then(Mono.empty())
|
|
||||||
))
|
|
||||||
.then(chain.filter(exchange));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,12 @@
|
||||||
package run.halo.app.security.authentication.rememberme;
|
package run.halo.app.security.authentication.rememberme;
|
||||||
|
|
||||||
|
import static org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher.MatchResult;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
|
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
|
||||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
import org.springframework.security.config.web.server.ServerHttpSecurity;
|
||||||
|
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
|
||||||
|
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
|
||||||
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
|
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.security.authentication.SecurityConfigurer;
|
import run.halo.app.security.authentication.SecurityConfigurer;
|
||||||
|
@ -10,19 +14,28 @@ import run.halo.app.security.authentication.SecurityConfigurer;
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RememberMeConfigurer implements SecurityConfigurer {
|
public class RememberMeConfigurer implements SecurityConfigurer {
|
||||||
|
|
||||||
private final RememberMeServices rememberMeServices;
|
private final RememberMeServices rememberMeServices;
|
||||||
|
|
||||||
private final ServerSecurityContextRepository securityContextRepository;
|
private final ServerSecurityContextRepository securityContextRepository;
|
||||||
|
|
||||||
private final CookieSignatureKeyResolver cookieSignatureKeyResolver;
|
private final CookieSignatureKeyResolver cookieSignatureKeyResolver;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(ServerHttpSecurity http) {
|
public void configure(ServerHttpSecurity http) {
|
||||||
http.addFilterAt(
|
var authManager = new RememberMeAuthenticationManager(cookieSignatureKeyResolver);
|
||||||
new RememberMeAuthenticationFilter(securityContextRepository,
|
var filter = new AuthenticationWebFilter(authManager);
|
||||||
rememberMeServices, authenticationManager()),
|
filter.setSecurityContextRepository(securityContextRepository);
|
||||||
SecurityWebFiltersOrder.AUTHENTICATION);
|
filter.setAuthenticationFailureHandler(
|
||||||
|
(exchange, exception) -> rememberMeServices.loginFail(exchange.getExchange())
|
||||||
|
);
|
||||||
|
filter.setServerAuthenticationConverter(rememberMeServices::autoLogin);
|
||||||
|
filter.setRequiresAuthenticationMatcher(
|
||||||
|
exchange -> ReactiveSecurityContextHolder.getContext()
|
||||||
|
.flatMap(securityContext -> MatchResult.notMatch())
|
||||||
|
.switchIfEmpty(MatchResult.match())
|
||||||
|
);
|
||||||
|
http.addFilterAt(filter, SecurityWebFiltersOrder.AUTHENTICATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
RememberMeAuthenticationManager authenticationManager() {
|
|
||||||
return new RememberMeAuthenticationManager(cookieSignatureKeyResolver);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue