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; } }