From bef2bbae0272e35ddb38fa84a1066f114f8b431b Mon Sep 17 00:00:00 2001 From: zhouhao Date: Wed, 21 Jun 2023 10:36:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20AuthorizationBeforeEvent=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E7=9B=B4=E6=8E=A5=E8=AE=BE=E7=BD=AE=E6=8E=88=E6=9D=83?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E4=BB=8E=E8=80=8C=E5=BF=BD=E7=95=A5=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E8=AE=A4=E8=AF=81=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../events/AuthorizationBeforeEvent.java | 21 +++++ .../basic/web/AuthorizationController.java | 80 ++++++++++++------- 2 files changed, 70 insertions(+), 31 deletions(-) diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/events/AuthorizationBeforeEvent.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/events/AuthorizationBeforeEvent.java index 2222a4a5a..eb3d4d5e4 100644 --- a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/events/AuthorizationBeforeEvent.java +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/events/AuthorizationBeforeEvent.java @@ -18,6 +18,9 @@ package org.hswebframework.web.authorization.events; +import lombok.Getter; +import org.hswebframework.web.authorization.Authentication; + import java.util.function.Function; /** @@ -26,11 +29,29 @@ import java.util.function.Function; * @author zhouhao * @since 3.0 */ +@Getter public class AuthorizationBeforeEvent extends AbstractAuthorizationEvent { private static final long serialVersionUID = 5948747533500518524L; + private String userId; + + private Authentication authentication; + public AuthorizationBeforeEvent(String username, String password, Function parameterGetter) { super(username, password, parameterGetter); } + + public void setAuthorized(String userId) { + this.userId = userId; + } + + public void setAuthorized(Authentication authentication) { + this.authentication = authentication; + } + + public boolean isAuthorized() { + return userId != null || authentication != null; + } + } diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/AuthorizationController.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/AuthorizationController.java index a8f553f04..a10024680 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/AuthorizationController.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/AuthorizationController.java @@ -22,6 +22,7 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.SneakyThrows; import org.hswebframework.web.authorization.Authentication; +import org.hswebframework.web.authorization.ReactiveAuthenticationHolder; import org.hswebframework.web.authorization.ReactiveAuthenticationManager; import org.hswebframework.web.authorization.annotation.Authorize; import org.hswebframework.web.authorization.events.AuthorizationBeforeEvent; @@ -62,13 +63,13 @@ public class AuthorizationController { @Operation(summary = "当前登录用户权限信息") public Mono me() { return Authentication.currentReactive() - .switchIfEmpty(Mono.error(UnAuthorizedException::new)); + .switchIfEmpty(Mono.error(UnAuthorizedException::new)); } @PostMapping(value = "/login", consumes = MediaType.APPLICATION_JSON_VALUE) @Authorize(ignore = true) @AccessLogger(ignore = true) - @Operation(summary = "登录",description = "必要参数:username,password.根据配置不同,其他参数也不同,如:验证码等.") + @Operation(summary = "登录", description = "必要参数:username,password.根据配置不同,其他参数也不同,如:验证码等.") public Mono> authorizeByJson(@Parameter(example = "{\"username\":\"admin\",\"password\":\"admin\"}") @RequestBody Mono> parameter) { return doLogin(parameter); @@ -88,37 +89,54 @@ public class AuthorizationController { Assert.hasLength(password_, "validation.password_must_not_be_empty"); Function parameterGetter = parameters::get; - return Mono.defer(() -> { - AuthorizationDecodeEvent decodeEvent = new AuthorizationDecodeEvent(username_, password_, parameterGetter); - return decodeEvent - .publish(eventPublisher) - .then(Mono.defer(() -> { - String username = decodeEvent.getUsername(); - String password = decodeEvent.getPassword(); - AuthorizationBeforeEvent beforeEvent = new AuthorizationBeforeEvent(username, password, parameterGetter); - return beforeEvent - .publish(eventPublisher) - .then(authenticationManager - .authenticate(Mono.just(new PlainTextUsernamePasswordAuthenticationRequest(username, password))) - .switchIfEmpty(Mono.error(() -> new AuthenticationException(AuthenticationException.ILLEGAL_PASSWORD))) - .flatMap(auth -> { - //触发授权成功事件 - AuthorizationSuccessEvent event = new AuthorizationSuccessEvent(auth, parameterGetter); - event.getResult().put("userId", auth.getUser().getId()); - return event - .publish(eventPublisher) - .then(Mono.fromCallable(event::getResult)); - })); - })); - }).onErrorResume(err -> { - AuthorizationFailedEvent failedEvent = new AuthorizationFailedEvent(username_, password_, parameterGetter); - failedEvent.setException(err); - return failedEvent - .publish(eventPublisher) - .then(Mono.error(failedEvent.getException())); - }); + return Mono + .defer(() -> { + AuthorizationDecodeEvent decodeEvent = new AuthorizationDecodeEvent(username_, password_, parameterGetter); + return decodeEvent + .publish(eventPublisher) + .then(Mono.defer(() -> { + String username = decodeEvent.getUsername(); + String password = decodeEvent.getPassword(); + AuthorizationBeforeEvent beforeEvent = new AuthorizationBeforeEvent(username, password, parameterGetter); + return beforeEvent + .publish(eventPublisher) + .then(Mono.defer(() -> doAuthorize(beforeEvent) + .flatMap(auth -> { + //触发授权成功事件 + AuthorizationSuccessEvent event = new AuthorizationSuccessEvent(auth, parameterGetter); + event.getResult().put("userId", auth.getUser().getId()); + return event + .publish(eventPublisher) + .then(Mono.fromCallable(event::getResult)); + }))); + })); + }) + .onErrorResume(err -> { + AuthorizationFailedEvent failedEvent = new AuthorizationFailedEvent(username_, password_, parameterGetter); + failedEvent.setException(err); + return failedEvent + .publish(eventPublisher) + .then(Mono.error(failedEvent.getException())); + }); }); + } + private Mono doAuthorize(AuthorizationBeforeEvent event) { + Mono authenticationMono; + if (event.isAuthorized()) { + if (event.getAuthentication() != null) { + authenticationMono = Mono.just(event.getAuthentication()); + } else { + authenticationMono = ReactiveAuthenticationHolder + .get(event.getUserId()) + .switchIfEmpty(Mono.error(() -> new AuthenticationException(AuthenticationException.USER_DISABLED))); + } + } else { + authenticationMono = authenticationManager + .authenticate(Mono.just(new PlainTextUsernamePasswordAuthenticationRequest(event.getUsername(), event.getPassword()))) + .switchIfEmpty(Mono.error(() -> new AuthenticationException(AuthenticationException.ILLEGAL_PASSWORD))); + } + return authenticationMono; } }