mirror of
https://github.com/hs-web/hsweb-framework.git
synced 2026-06-02 02:43:59 +08:00
优化认证
This commit is contained in:
@@ -31,6 +31,7 @@ public class AuthorizationFailedEvent extends AbstractAuthorizationEvent {
|
||||
/**
|
||||
* 失败原因
|
||||
*/
|
||||
@Deprecated//已弃用,请根据exception判断
|
||||
private Reason reason;
|
||||
|
||||
/**
|
||||
@@ -58,6 +59,7 @@ public class AuthorizationFailedEvent extends AbstractAuthorizationEvent {
|
||||
return reason;
|
||||
}
|
||||
|
||||
@Deprecated//已弃用,请根据exception判断
|
||||
public enum Reason {
|
||||
PASSWORD_ERROR,
|
||||
USER_DISABLED,
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.hswebframework.web.authorization.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class AuthenticationException extends RuntimeException {
|
||||
|
||||
|
||||
public static String ILLEGAL_PASSWORD = "illegal_password";
|
||||
|
||||
public static String USER_DISABLED = "user_disabled";
|
||||
|
||||
|
||||
private final String code;
|
||||
|
||||
public AuthenticationException(String code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public AuthenticationException(String code, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,11 @@ import org.hswebframework.web.authorization.events.AuthorizationBeforeEvent;
|
||||
import org.hswebframework.web.authorization.events.AuthorizationDecodeEvent;
|
||||
import org.hswebframework.web.authorization.events.AuthorizationFailedEvent;
|
||||
import org.hswebframework.web.authorization.events.AuthorizationSuccessEvent;
|
||||
import org.hswebframework.web.authorization.exception.AuthenticationException;
|
||||
import org.hswebframework.web.authorization.exception.UnAuthorizedException;
|
||||
import org.hswebframework.web.authorization.simple.CompositeReactiveAuthenticationManager;
|
||||
import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest;
|
||||
import org.hswebframework.web.logging.AccessLogger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -65,19 +67,12 @@ public class AuthorizationController {
|
||||
@PostMapping(value = "/login", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ApiOperation("用户名密码登录,json方式")
|
||||
@Authorize(ignore = true)
|
||||
@AccessLogger(ignore = true)
|
||||
public Mono<Map<String, Object>> authorizeByJson(@ApiParam(example = "{\"username\":\"admin\",\"password\":\"admin\"}")
|
||||
@RequestBody Mono<Map<String, Object>> parameter) {
|
||||
return doLogin(parameter);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
@ApiOperation("用户名密码登录,参数方式")
|
||||
@Authorize(ignore = true)
|
||||
public Mono<Map<String, Object>> authorizeByUrlEncoded(@ApiParam(hidden = true) @RequestParam Map<String, Object> parameter) {
|
||||
|
||||
return doLogin(Mono.just(parameter));
|
||||
}
|
||||
|
||||
/**
|
||||
* <img src="https://raw.githubusercontent.com/hs-web/hsweb-framework/4.0.x/hsweb-authorization/hsweb-authorization-basic/img/autz-flow.png">
|
||||
*/
|
||||
@@ -105,7 +100,7 @@ public class AuthorizationController {
|
||||
.publish(eventPublisher)
|
||||
.then(authenticationManager
|
||||
.authenticate(Mono.just(new PlainTextUsernamePasswordAuthenticationRequest(username, password)))
|
||||
.switchIfEmpty(Mono.error(() -> new IllegalArgumentException("密码错误")))
|
||||
.switchIfEmpty(Mono.error(() -> new AuthenticationException(AuthenticationException.ILLEGAL_PASSWORD,"密码错误")))
|
||||
.flatMap(auth -> {
|
||||
//触发授权成功事件
|
||||
AuthorizationSuccessEvent event = new AuthorizationSuccessEvent(auth, parameterGetter);
|
||||
@@ -114,7 +109,6 @@ public class AuthorizationController {
|
||||
.publish(eventPublisher)
|
||||
.then(Mono.fromCallable(event::getResult));
|
||||
}));
|
||||
|
||||
}));
|
||||
}).onErrorResume(err -> {
|
||||
AuthorizationFailedEvent failedEvent = new AuthorizationFailedEvent(username_, password_, parameterGetter, reason);
|
||||
|
||||
@@ -82,34 +82,17 @@ public class RedisReactiveCache<E> implements ReactiveCache<E> {
|
||||
|
||||
@Override
|
||||
public Mono<Void> put(Object key, Publisher<E> data) {
|
||||
if (data instanceof Mono) {
|
||||
return ((Mono<?>) data)
|
||||
.flatMap(r -> {
|
||||
return operations.opsForHash()
|
||||
.put(redisKey, key, r)
|
||||
.then(localCache.put(key, data))
|
||||
.then(operations.convertAndSend(topicName, key));
|
||||
|
||||
})
|
||||
.then()
|
||||
.onErrorResume(err -> this.handleError(err))
|
||||
;
|
||||
}
|
||||
if (data instanceof Flux) {
|
||||
return ((Flux<?>) data)
|
||||
.collectList()
|
||||
.flatMap(r -> {
|
||||
return operations.opsForHash()
|
||||
.put(redisKey, key, r)
|
||||
.then(localCache.put(key, data))
|
||||
.then(operations.convertAndSend(topicName, key));
|
||||
|
||||
})
|
||||
.then()
|
||||
.onErrorResume(err -> this.handleError(err))
|
||||
;
|
||||
}
|
||||
return Mono.error(new UnsupportedOperationException("unsupport publisher:" + data));
|
||||
return Flux
|
||||
.from(data)
|
||||
.collectList()
|
||||
.flatMap(r -> {
|
||||
return operations.opsForHash()
|
||||
.put(redisKey, key, r)
|
||||
.then(localCache.put(key, data))
|
||||
.then(operations.convertAndSend(topicName, key));
|
||||
})
|
||||
.then()
|
||||
.onErrorResume(err -> this.handleError(err));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,7 +33,7 @@ public @interface AccessLogger {
|
||||
* @return 对类或方法的简单说明
|
||||
* @see AccessLoggerInfo#getAction()
|
||||
*/
|
||||
String value();
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* @return 对类或方法的详细描述
|
||||
|
||||
@@ -29,22 +29,21 @@ public class DefaultReactiveAuthenticationManager implements ReactiveAuthenticat
|
||||
@Autowired(required = false)
|
||||
private ReactiveCacheManager cacheManager;
|
||||
|
||||
|
||||
@EventListener
|
||||
public void handleClearAuthCache(ClearUserAuthorizationCacheEvent event) {
|
||||
if (cacheManager != null) {
|
||||
if (event.isAll()) {
|
||||
cacheManager.getCache("user-auth")
|
||||
.clear()
|
||||
.doOnSuccess(nil->log.info("clear all user authentication cache success"))
|
||||
.doOnSuccess(nil -> log.info("clear all user authentication cache success"))
|
||||
.doOnError(err -> log.error(err.getMessage(), err))
|
||||
.subscribe();
|
||||
} else {
|
||||
cacheManager.getCache("user-auth")
|
||||
.evictAll(event.getUserId())
|
||||
.doOnError(err -> log.error(err.getMessage(), err))
|
||||
.doOnSuccess(__->log.info("clear user {} authentication cache success", event.getUserId()))
|
||||
.subscribe( );
|
||||
.doOnSuccess(__ -> log.info("clear user {} authentication cache success", event.getUserId()))
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +55,7 @@ public class DefaultReactiveAuthenticationManager implements ReactiveAuthenticat
|
||||
.switchIfEmpty(Mono.error(() -> new UnsupportedOperationException("不支持的请求类型")))
|
||||
.map(PlainTextUsernamePasswordAuthenticationRequest.class::cast)
|
||||
.flatMap(pwdRequest -> reactiveUserService.findByUsernameAndPassword(pwdRequest.getUsername(), pwdRequest.getPassword()))
|
||||
.switchIfEmpty(Mono.error(() -> new AccessDenyException("密码错误")))
|
||||
.filter(user -> Byte.valueOf((byte) 1).equals(user.getStatus()))
|
||||
.map(UserEntity::getId)
|
||||
.flatMap(this::getByUserId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user