Skip to content

Commit c610b0a

Browse files
authored
Refactor authorization configuration to enhance access control and add cancel link in TOTP forms (#8182)
#### What type of PR is this? /kind improvement /area core /milestone 2.22.x #### What this PR does / why we need it: This PR refactors authorization configuration to enhance access control and add cancel link in TOTP forms. So that we can cancel TOTP authentication by being able to redirect to logout page. #### Which issue(s) this PR fixes: Fixes #8172 #### Special notes for your reviewer: 1. Try to configure TOTP for your own account 2. Try to logout and login 3. Click the cancel link and you will be redirected to logout page 4. Try to click the logout button #### Does this PR introduce a user-facing change? ```release-note 优化二步验证登录体验 ```
1 parent b45902c commit c610b0a

File tree

7 files changed

+43
-12
lines changed

7 files changed

+43
-12
lines changed

application/src/main/java/run/halo/app/security/authorization/AuthorizationExchangeConfigurers.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import reactor.core.publisher.Mono;
2020
import run.halo.app.core.user.service.RoleService;
2121
import run.halo.app.security.authentication.SecurityConfigurer;
22+
import run.halo.app.security.authentication.twofactor.TwoFactorAuthentication;
2223

2324
/**
2425
* Authorization exchange configurers.
@@ -61,13 +62,25 @@ SecurityConfigurer preAuthenticationAuthorizationConfigurer() {
6162
.hasRole(AuthorityUtils.SUPER_ROLE_NAME)
6263
.pathMatchers("/logout/impersonate")
6364
.hasAuthority(SwitchUserWebFilter.ROLE_PREVIOUS_ADMINISTRATOR)
65+
.pathMatchers("/challenges/**")
66+
.access((authentication, context) ->
67+
authentication.map(TwoFactorAuthentication.class::isInstance)
68+
.map(AuthorizationDecision::new)
69+
.switchIfEmpty(Mono.fromSupplier(() -> new AuthorizationDecision(false)))
70+
)
6471
.pathMatchers(
6572
"/login/**",
66-
"/challenges/**",
6773
"/password-reset/**",
6874
"/signup"
6975
)
70-
.permitAll());
76+
.permitAll()
77+
.pathMatchers("/logout")
78+
.access((authentication, context) ->
79+
authentication.map(a -> !authenticationTrustResolver.isAnonymous(a))
80+
.map(AuthorizationDecision::new)
81+
.switchIfEmpty(Mono.fromSupplier(() -> new AuthorizationDecision(false)))
82+
)
83+
);
7184
}
7285

7386
@Bean
@@ -76,10 +89,10 @@ SecurityConfigurer authenticatedAuthorizationConfigurer() {
7689
// Anonymous user is not allowed
7790
return http -> http.authorizeExchange(
7891
spec -> spec.pathMatchers(
79-
"/console/**",
80-
"/uc/**",
81-
"/logout"
82-
).authenticated()
92+
"/console/**",
93+
"/uc/**"
94+
)
95+
.authenticated()
8396
);
8497
}
8598

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
<!doctype html>
22
<html
33
xmlns:th="https://www.thymeleaf.org"
4-
th:replace="~{gateway_fragments/layout :: layout(title = |#{title} - ${site.title}|, head = null, body = ~{::body})}"
4+
th:replace="~{gateway_fragments/layout :: layout(title = |#{title} - ${site.title}|, head = ~{::head}, body = ~{::body})}"
55
>
66
<th:block th:fragment="body">
7-
<div class="gateway-wrapper">
7+
<div class="gateway-wrapper totp-page-wrapper">
88
<div th:replace="~{gateway_fragments/common::haloLogo}"></div>
99
<div class="halo-form-wrapper">
1010
<h1 class="form-title" th:text="#{title}"></h1>
1111
<form th:replace="~{gateway_fragments/totp::form}"></form>
1212
</div>
1313
</div>
1414
</th:block>
15+
16+
<th:block th:fragment="head">
17+
<style>
18+
.totp-page-wrapper .cancel-link {
19+
color: var(--color-link);
20+
font-size: var(--text-sm);
21+
text-decoration: none;
22+
text-align: center;
23+
}
24+
</style>
25+
</th:block>
1526
</html>

application/src/main/resources/templates/gateway_fragments/totp.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,7 @@
2727
<div class="form-item">
2828
<button type="submit" th:text="#{form.submit}"></button>
2929
</div>
30+
<div class="form-item">
31+
<a th:href="@{/logout}" class="cancel-link" th:text="#{form.cancel}"></a>
32+
</div>
3033
</form>
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
form.messages.invalidError=错误的验证码
22
form.code.label=验证码
3-
form.submit=验证
3+
form.submit=验证
4+
form.cancel=取消
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
form.messages.invalidError=Invalid TOTP code
22
form.code.label=TOTP Code
3-
form.submit=Verify
3+
form.submit=Verify
4+
form.cancel=Cancel
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
form.messages.invalidError=Código de verificación incorrecto
22
form.code.label=Código de Verificación
3-
form.submit=Verificar
3+
form.submit=Verificar
4+
form.cancel=Cancelar
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
form.messages.invalidError=錯誤的驗證碼
22
form.code.label=驗證碼
3-
form.submit=驗證
3+
form.submit=驗證
4+
form.cancel=取消

0 commit comments

Comments
 (0)