feat: AuthorizationBeforeEvent可以直接设置授权信息从而忽略默认认证逻辑

This commit is contained in:
zhouhao
2023-06-21 10:36:13 +08:00
parent cb5a2cb7c5
commit bef2bbae02
2 changed files with 70 additions and 31 deletions

View File

@@ -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<Authentication> 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<Map<String, Object>> authorizeByJson(@Parameter(example = "{\"username\":\"admin\",\"password\":\"admin\"}")
@RequestBody Mono<Map<String, Object>> parameter) {
return doLogin(parameter);
@@ -88,37 +89,54 @@ public class AuthorizationController {
Assert.hasLength(password_, "validation.password_must_not_be_empty");
Function<String, Object> 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<Authentication> doAuthorize(AuthorizationBeforeEvent event) {
Mono<Authentication> 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;
}
}