mirror of https://github.com/halo-dev/halo
Disable CSRF check for PAT authentication (#7353)
#### What type of PR is this? /kind improvement /area core /milestone 2.20.x #### What this PR does / why we need it: This PR disables CSRF check for PAT authentication because the authentication won't pass any cookies to server. #### Does this PR introduce a user-facing change? ```release-note None ```pull/7364/head
parent
e0b9c50d71
commit
222e955a66
|
@ -9,8 +9,11 @@ import org.springframework.security.web.server.csrf.CsrfWebFilter;
|
||||||
import org.springframework.security.web.server.csrf.XorServerCsrfTokenRequestAttributeHandler;
|
import org.springframework.security.web.server.csrf.XorServerCsrfTokenRequestAttributeHandler;
|
||||||
import org.springframework.security.web.server.util.matcher.AndServerWebExchangeMatcher;
|
import org.springframework.security.web.server.util.matcher.AndServerWebExchangeMatcher;
|
||||||
import org.springframework.security.web.server.util.matcher.NegatedServerWebExchangeMatcher;
|
import org.springframework.security.web.server.util.matcher.NegatedServerWebExchangeMatcher;
|
||||||
|
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
import run.halo.app.security.authentication.SecurityConfigurer;
|
import run.halo.app.security.authentication.SecurityConfigurer;
|
||||||
|
import run.halo.app.security.authentication.pat.PatAuthenticationConverter;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Order(0)
|
@Order(0)
|
||||||
|
@ -25,7 +28,8 @@ class CsrfConfigurer implements SecurityConfigurer {
|
||||||
"/apis/**",
|
"/apis/**",
|
||||||
"/actuator/**",
|
"/actuator/**",
|
||||||
"/system/setup"
|
"/system/setup"
|
||||||
))
|
)),
|
||||||
|
new NegatedServerWebExchangeMatcher(patAuthMatcher())
|
||||||
);
|
);
|
||||||
http.csrf(csrfSpec -> csrfSpec
|
http.csrf(csrfSpec -> csrfSpec
|
||||||
.csrfTokenRepository(new CookieServerCsrfTokenRepository())
|
.csrfTokenRepository(new CookieServerCsrfTokenRepository())
|
||||||
|
@ -33,4 +37,11 @@ class CsrfConfigurer implements SecurityConfigurer {
|
||||||
.requireCsrfProtectionMatcher(csrfMatcher));
|
.requireCsrfProtectionMatcher(csrfMatcher));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ServerWebExchangeMatcher patAuthMatcher() {
|
||||||
|
var patConverter = new PatAuthenticationConverter();
|
||||||
|
return exchange -> patConverter.convert(exchange)
|
||||||
|
.flatMap(a -> ServerWebExchangeMatcher.MatchResult.match())
|
||||||
|
.switchIfEmpty(Mono.defer(ServerWebExchangeMatcher.MatchResult::notMatch));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import reactor.core.publisher.Mono;
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @since 2.20.4
|
* @since 2.20.4
|
||||||
*/
|
*/
|
||||||
class PatAuthenticationConverter extends ServerBearerTokenAuthenticationConverter {
|
public class PatAuthenticationConverter extends ServerBearerTokenAuthenticationConverter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Authentication> convert(ServerWebExchange exchange) {
|
public Mono<Authentication> convert(ServerWebExchange exchange) {
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package run.halo.app.security;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@AutoConfigureWebTestClient
|
||||||
|
class CsrfSecurityTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
WebTestClient webClient;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldNotCheckCsrfForPatAuthentication() {
|
||||||
|
webClient.post()
|
||||||
|
.uri("/fake")
|
||||||
|
.headers(headers -> headers.setBearerAuth("pat_invalid"))
|
||||||
|
.exchange()
|
||||||
|
.expectStatus()
|
||||||
|
.isUnauthorized()
|
||||||
|
.expectHeader()
|
||||||
|
.exists(HttpHeaders.WWW_AUTHENTICATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue