forked from halo-dev/halo
-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'upstream/main'
- Loading branch information
Showing
3 changed files
with
46 additions
and
125 deletions.
There are no files selected for viewing
43 changes: 0 additions & 43 deletions
43
application/src/main/java/run/halo/app/config/HaloAnonymousAuthenticationWebFilter.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 20 additions & 32 deletions
52
application/src/main/java/run/halo/app/theme/dialect/HaloSpringSecurityDialect.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,53 @@ | ||
package run.halo.app.theme.dialect; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import static org.springframework.security.core.authority.AuthorityUtils.createAuthorityList; | ||
import static run.halo.app.infra.AnonymousUserConst.PRINCIPAL; | ||
import static run.halo.app.infra.AnonymousUserConst.Role; | ||
|
||
import java.util.function.Function; | ||
import org.springframework.security.web.reactive.result.view.CsrfRequestDataValueProcessor; | ||
import org.springframework.beans.factory.InitializingBean; | ||
import org.springframework.security.authentication.AnonymousAuthenticationToken; | ||
import org.springframework.security.core.context.SecurityContextImpl; | ||
import org.springframework.security.web.server.context.ServerSecurityContextRepository; | ||
import org.springframework.security.web.server.csrf.CsrfToken; | ||
import org.springframework.web.server.ServerWebExchange; | ||
import org.thymeleaf.extras.springsecurity6.dialect.SpringSecurityDialect; | ||
import org.thymeleaf.extras.springsecurity6.util.SpringSecurityContextUtils; | ||
import org.thymeleaf.extras.springsecurity6.util.SpringVersionUtils; | ||
import reactor.core.publisher.Mono; | ||
|
||
/** | ||
* HaloSpringSecurityDialect overwrites value of thymeleafSpringSecurityContext. | ||
* | ||
* @author johnniang | ||
*/ | ||
public class HaloSpringSecurityDialect extends SpringSecurityDialect { | ||
public class HaloSpringSecurityDialect extends SpringSecurityDialect implements InitializingBean { | ||
|
||
private static final String SECURITY_CONTEXT_EXECUTION_ATTRIBUTE_NAME = | ||
"ThymeleafReactiveModelAdditions:" | ||
+ SpringSecurityContextUtils.SECURITY_CONTEXT_MODEL_ATTRIBUTE_NAME; | ||
private static final String CSRF_EXECUTION_ATTRIBUTE_NAME = | ||
"ThymeleafReactiveModelAdditions:" + CsrfRequestDataValueProcessor.DEFAULT_CSRF_ATTR_NAME; | ||
|
||
private final Map<String, Object> executionAttributes; | ||
|
||
private final ServerSecurityContextRepository securityContextRepository; | ||
|
||
public HaloSpringSecurityDialect(ServerSecurityContextRepository securityContextRepository) { | ||
this.securityContextRepository = securityContextRepository; | ||
executionAttributes = new HashMap<>(3, 1.0f); | ||
initExecutionAttributes(); | ||
} | ||
|
||
private void initExecutionAttributes() { | ||
@Override | ||
public void afterPropertiesSet() { | ||
if (!SpringVersionUtils.isSpringWebFluxPresent()) { | ||
return; | ||
} | ||
|
||
final Function<ServerWebExchange, Object> secCtxInitializer = | ||
(exchange) -> securityContextRepository.load(exchange); | ||
|
||
final Function<ServerWebExchange, Object> csrfTokenInitializer = | ||
(exchange) -> { | ||
final Mono<CsrfToken> csrfToken = exchange.getAttribute(CsrfToken.class.getName()); | ||
if (csrfToken == null) { | ||
return Mono.empty(); | ||
} | ||
return csrfToken.doOnSuccess( | ||
token -> exchange.getAttributes() | ||
.put(CsrfRequestDataValueProcessor.DEFAULT_CSRF_ATTR_NAME, token)); | ||
}; | ||
// We have to build an anonymous authentication token here because the token won't be saved | ||
// into repository during anonymous authentication. | ||
var anonymousAuthentication = | ||
new AnonymousAuthenticationToken("fallback", PRINCIPAL, createAuthorityList(Role)); | ||
var anonymousSecurityContext = new SecurityContextImpl(anonymousAuthentication); | ||
|
||
executionAttributes.put(SECURITY_CONTEXT_EXECUTION_ATTRIBUTE_NAME, secCtxInitializer); | ||
executionAttributes.put(CSRF_EXECUTION_ATTRIBUTE_NAME, csrfTokenInitializer); | ||
} | ||
final Function<ServerWebExchange, Object> secCtxInitializer = | ||
exchange -> securityContextRepository.load(exchange) | ||
.defaultIfEmpty(anonymousSecurityContext); | ||
|
||
@Override | ||
public Map<String, Object> getExecutionAttributes() { | ||
return executionAttributes; | ||
// Just overwrite the value of the attribute | ||
getExecutionAttributes().put(SECURITY_CONTEXT_EXECUTION_ATTRIBUTE_NAME, secCtxInitializer); | ||
} | ||
} |