mirror of
https://github.com/hs-web/hsweb-framework.git
synced 2026-06-09 17:34:50 +08:00
backup
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
|
||||
package org.hswebframework.web.authorization;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
@@ -50,8 +52,8 @@ public interface Authentication extends Serializable {
|
||||
* @see Optional
|
||||
* @see AuthenticationHolder
|
||||
*/
|
||||
static Optional<Authentication> current() {
|
||||
return Optional.ofNullable(AuthenticationHolder.get());
|
||||
static Mono<Authentication> current() {
|
||||
return AuthenticationHolder.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
package org.hswebframework.web.authorization;
|
||||
|
||||
import org.hswebframework.web.ThreadLocalUtils;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -26,6 +28,7 @@ import java.util.Objects;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 权限获取器,用于静态方式获取当前登录用户的权限信息.
|
||||
@@ -45,31 +48,23 @@ import java.util.function.Function;
|
||||
public final class AuthenticationHolder {
|
||||
private static final List<AuthenticationSupplier> suppliers = new ArrayList<>();
|
||||
|
||||
private static final String CURRENT_USER_ID_KEY = Authentication.class.getName() + "_current_id";
|
||||
|
||||
private static final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
private static Authentication get(Function<AuthenticationSupplier, Authentication> function) {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
return suppliers.stream()
|
||||
.map(function)
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
private static Mono<Authentication> get(Function<AuthenticationSupplier, Mono<Authentication>> function) {
|
||||
|
||||
return Flux.concat(suppliers.stream()
|
||||
.map(function)
|
||||
.collect(Collectors.toList()))
|
||||
.reduceWith(CompositeAuthentication::new, CompositeAuthentication::merge)
|
||||
.filter(CompositeAuthentication::isNotEmpty)
|
||||
.map(Authentication.class::cast);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 当前登录的用户权限信息
|
||||
*/
|
||||
public static Authentication get() {
|
||||
String currentId = ThreadLocalUtils.get(CURRENT_USER_ID_KEY);
|
||||
if (currentId != null) {
|
||||
return get(currentId);
|
||||
}
|
||||
public static Mono<Authentication> get() {
|
||||
|
||||
return get(AuthenticationSupplier::get);
|
||||
}
|
||||
|
||||
@@ -79,7 +74,7 @@ public final class AuthenticationHolder {
|
||||
* @param userId 用户ID
|
||||
* @return 权限信息
|
||||
*/
|
||||
public static Authentication get(String userId) {
|
||||
public static Mono<Authentication> get(String userId) {
|
||||
return get(supplier -> supplier.get(userId));
|
||||
}
|
||||
|
||||
@@ -97,7 +92,4 @@ public final class AuthenticationHolder {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setCurrentUserId(String id) {
|
||||
ThreadLocalUtils.put(AuthenticationHolder.CURRENT_USER_ID_KEY, id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
package org.hswebframework.web.authorization;
|
||||
|
||||
import org.hswebframework.web.authorization.listener.event.AuthorizationInitializeEvent;
|
||||
import org.hswebframework.web.authorization.events.AuthorizationInitializeEvent;
|
||||
|
||||
/**
|
||||
* 授权信息初始化服务接口,使用该接口初始化用的权限信息
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
package org.hswebframework.web.authorization;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -36,7 +38,7 @@ public interface AuthenticationManager {
|
||||
* @param request 授权请求
|
||||
* @return 授权成功则返回用户权限信息
|
||||
*/
|
||||
Authentication authenticate(AuthenticationRequest request);
|
||||
Mono<Authentication> authenticate(AuthenticationRequest request);
|
||||
|
||||
/**
|
||||
* 根据用户ID获取权限信息
|
||||
@@ -44,7 +46,7 @@ public interface AuthenticationManager {
|
||||
* @param userId 用户ID
|
||||
* @return 权限信息
|
||||
*/
|
||||
Authentication getByUserId(String userId);
|
||||
Mono<Authentication> getByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 同步授权信息,在调用了{@link Authentication#setAttribute(String, Serializable)}或者
|
||||
@@ -56,5 +58,5 @@ public interface AuthenticationManager {
|
||||
* @param authentication 要同步的权限信息
|
||||
* @return 同步后的权限信息
|
||||
*/
|
||||
Authentication sync(Authentication authentication);
|
||||
Mono<Authentication> sync(Authentication authentication);
|
||||
}
|
||||
|
||||
@@ -44,17 +44,7 @@ public interface AuthenticationPredicate extends Predicate<Authentication> {
|
||||
return (t) -> test(t) || other.test(t);
|
||||
}
|
||||
|
||||
default boolean test() {
|
||||
return Authentication.current()
|
||||
.map(this::test)
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
default void assertHas() {
|
||||
if (!test()) {
|
||||
throw new AccessDenyException();
|
||||
}
|
||||
}
|
||||
|
||||
default void assertHas(Authentication authentication) {
|
||||
if (!test(authentication)) {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package org.hswebframework.web.authorization;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
@@ -25,6 +27,6 @@ import java.util.function.Supplier;
|
||||
* @see Authentication
|
||||
* @see AuthenticationHolder
|
||||
*/
|
||||
public interface AuthenticationSupplier extends Supplier<Authentication> {
|
||||
Authentication get(String userId);
|
||||
public interface AuthenticationSupplier extends Supplier<Mono<Authentication>> {
|
||||
Mono<Authentication> get(String userId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package org.hswebframework.web.authorization;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CompositeAuthentication implements Authentication {
|
||||
|
||||
private Map<String, Authentication> userAuthentication = new ConcurrentHashMap<>();
|
||||
|
||||
private String currentUser;
|
||||
|
||||
public boolean isEmpty() {
|
||||
return userAuthentication.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isNotEmpty() {
|
||||
return !isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public User getUser() {
|
||||
|
||||
return userAuthentication
|
||||
.get(currentUser)
|
||||
.getUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Role> getRoles() {
|
||||
return userAuthentication.values()
|
||||
.stream()
|
||||
.map(Authentication::getRoles)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Permission> getPermissions() {
|
||||
return userAuthentication.values()
|
||||
.stream()
|
||||
.map(Authentication::getPermissions)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Serializable> Optional<T> getAttribute(String name) {
|
||||
return userAuthentication.values()
|
||||
.stream()
|
||||
.map(a -> a.<T>getAttribute(name))
|
||||
.filter(Optional::isPresent)
|
||||
.findAny()
|
||||
.flatMap(Function.identity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, Serializable object) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttributes(Map<String, Serializable> attributes) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Serializable> T removeAttributes(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Serializable> getAttributes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CompositeAuthentication merge(Authentication authentication) {
|
||||
String userId = authentication.getUser().getId();
|
||||
if (currentUser == null) {
|
||||
currentUser = userId;
|
||||
}
|
||||
userAuthentication.put(userId, authentication);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.hswebframework.web.authorization.define;
|
||||
|
||||
import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
|
||||
import org.hswebframework.web.authorization.events.AuthorizationEvent;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.hswebframework.web.authorization.listener.event;
|
||||
package org.hswebframework.web.authorization.events;
|
||||
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.hswebframework.web.authorization.listener.event;
|
||||
package org.hswebframework.web.authorization.events;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.hswebframework.web.authorization.listener.event;
|
||||
package org.hswebframework.web.authorization.events;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.hswebframework.web.authorization.listener.event;
|
||||
package org.hswebframework.web.authorization.events;
|
||||
|
||||
/**
|
||||
* 授权事件
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.hswebframework.web.authorization.listener.event;
|
||||
package org.hswebframework.web.authorization.events;
|
||||
|
||||
import org.hswebframework.web.authorization.Authentication;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.hswebframework.web.authorization.listener.event;
|
||||
package org.hswebframework.web.authorization.events;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.hswebframework.web.authorization.listener.event;
|
||||
package org.hswebframework.web.authorization.events;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package org.hswebframework.web.authorization.listener.event;
|
||||
package org.hswebframework.web.authorization.events;
|
||||
|
||||
import org.hswebframework.web.authorization.Authentication;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.hswebframework.web.authorization.listener.event;
|
||||
package org.hswebframework.web.authorization.events;
|
||||
|
||||
import org.hswebframework.web.authorization.define.AuthorizingContext;
|
||||
import org.hswebframework.web.authorization.define.HandleType;
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.hswebframework.web.authorization.token;
|
||||
|
||||
import org.hswebframework.web.authorization.Authentication;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* @author zhouhao
|
||||
@@ -19,6 +20,6 @@ public interface ThirdPartAuthenticationManager {
|
||||
* @param userId 用户ID
|
||||
* @return 权限信息
|
||||
*/
|
||||
Authentication getByUserId(String userId);
|
||||
Mono<Authentication> getByUserId(String userId);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package org.hswebframework.web.authorization.token;
|
||||
|
||||
import org.hswebframework.web.ThreadLocalUtils;
|
||||
import org.hswebframework.web.authorization.Authentication;
|
||||
import org.hswebframework.web.authorization.AuthenticationManager;
|
||||
import org.hswebframework.web.authorization.AuthenticationSupplier;
|
||||
import org.hswebframework.web.context.ContextKey;
|
||||
import org.hswebframework.web.context.ContextUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author zhouhao
|
||||
@@ -32,14 +33,14 @@ public class UserTokenAuthenticationSupplier implements AuthenticationSupplier {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication get(String userId) {
|
||||
public Mono<Authentication> get(String userId) {
|
||||
if (userId == null) {
|
||||
return null;
|
||||
}
|
||||
return get(this.defaultAuthenticationManager, userId);
|
||||
}
|
||||
|
||||
protected Authentication get(ThirdPartAuthenticationManager authenticationManager, String userId) {
|
||||
protected Mono<Authentication> get(ThirdPartAuthenticationManager authenticationManager, String userId) {
|
||||
if (null == userId) {
|
||||
return null;
|
||||
}
|
||||
@@ -49,7 +50,7 @@ public class UserTokenAuthenticationSupplier implements AuthenticationSupplier {
|
||||
return authenticationManager.getByUserId(userId);
|
||||
}
|
||||
|
||||
protected Authentication get(AuthenticationManager authenticationManager, String userId) {
|
||||
protected Mono<Authentication> get(AuthenticationManager authenticationManager, String userId) {
|
||||
if (null == userId) {
|
||||
return null;
|
||||
}
|
||||
@@ -59,19 +60,14 @@ public class UserTokenAuthenticationSupplier implements AuthenticationSupplier {
|
||||
return authenticationManager.getByUserId(userId);
|
||||
}
|
||||
|
||||
protected UserToken getCurrentUserToken() {
|
||||
return UserTokenHolder.currentToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication get() {
|
||||
return ThreadLocalUtils.get(Authentication.class.getName(), () ->
|
||||
Optional.ofNullable(getCurrentUserToken())
|
||||
.filter(UserToken::validate) //验证token,如果不是正常状态,将会抛出异常
|
||||
.map(token ->
|
||||
get(thirdPartAuthenticationManager
|
||||
.get(token.getType()), token.getUserId())
|
||||
)
|
||||
.orElse(null));
|
||||
public Mono<Authentication> get() {
|
||||
return ContextUtils.currentContext()
|
||||
.flatMap(context ->
|
||||
context.get(ContextKey.of(UserToken.class))
|
||||
.filter(UserToken::validate)
|
||||
.map(token -> get(thirdPartAuthenticationManager.get(token.getType()), token.getUserId()))
|
||||
.orElseGet(Mono::empty));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.hswebframework.web.authorization.token.event;
|
||||
|
||||
import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
|
||||
import org.hswebframework.web.authorization.events.AuthorizationEvent;
|
||||
import org.hswebframework.web.authorization.token.UserToken;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.hswebframework.web.authorization.token.event;
|
||||
|
||||
import org.hswebframework.web.authorization.token.UserToken;
|
||||
import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
|
||||
import org.hswebframework.web.authorization.events.AuthorizationEvent;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
public class UserTokenCreatedEvent extends ApplicationEvent implements AuthorizationEvent {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.hswebframework.web.authorization.token.event;
|
||||
|
||||
import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
|
||||
import org.hswebframework.web.authorization.events.AuthorizationEvent;
|
||||
import org.hswebframework.web.authorization.token.UserToken;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
package org.hswebframework.web.authorization;
|
||||
|
||||
import org.hswebframework.web.authorization.builder.AuthenticationBuilder;
|
||||
import org.hswebframework.web.authorization.exception.AccessDenyException;
|
||||
import org.hswebframework.web.authorization.exception.UnAuthorizedException;
|
||||
import org.hswebframework.web.authorization.simple.builder.SimpleAuthenticationBuilder;
|
||||
import org.hswebframework.web.authorization.simple.builder.SimpleDataAccessConfigBuilderFactory;
|
||||
import org.hswebframework.web.authorization.token.*;
|
||||
import org.hswebframework.web.context.ContextKey;
|
||||
import org.hswebframework.web.context.ContextUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hswebframework.web.context.ContextUtils.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class AuthenticationTests {
|
||||
@@ -54,7 +60,7 @@ public class AuthenticationTests {
|
||||
assertEquals(authentication.getPermissions().size(), 1);
|
||||
assertTrue(authentication.hasPermission("user-manager"));
|
||||
assertTrue(authentication.hasPermission("user-manager", "get"));
|
||||
assertTrue(!authentication.hasPermission("user-manager", "delete"));
|
||||
assertFalse(authentication.hasPermission("user-manager", "delete"));
|
||||
|
||||
boolean has = AuthenticationPredicate.has("permission:user-manager")
|
||||
.or(AuthenticationPredicate.role("admin-role"))
|
||||
@@ -95,21 +101,21 @@ public class AuthenticationTests {
|
||||
//初始化权限管理器,用于获取用户的权限信息
|
||||
AuthenticationManager authenticationManager = new AuthenticationManager() {
|
||||
@Override
|
||||
public Authentication authenticate(AuthenticationRequest request) {
|
||||
public Mono<Authentication> authenticate(AuthenticationRequest request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication getByUserId(String userId) {
|
||||
public Mono<Authentication> getByUserId(String userId) {
|
||||
if (userId.equals("admin")) {
|
||||
return authentication;
|
||||
return Mono.just(authentication);
|
||||
}
|
||||
return null;
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication sync(Authentication authentication) {
|
||||
return authentication;
|
||||
public Mono<Authentication> sync(Authentication authentication) {
|
||||
return Mono.just(authentication);
|
||||
}
|
||||
};
|
||||
AuthenticationHolder.addSupplier(new UserTokenAuthenticationSupplier(authenticationManager));
|
||||
@@ -117,11 +123,16 @@ public class AuthenticationTests {
|
||||
//绑定用户token
|
||||
UserTokenManager userTokenManager = new DefaultUserTokenManager();
|
||||
UserToken token = userTokenManager.signIn("test", "token-test", "admin", -1);
|
||||
UserTokenHolder.setCurrent(token);
|
||||
|
||||
//获取当前登录用户
|
||||
Authentication current = Authentication.current().orElseThrow(UnAuthorizedException::new);
|
||||
Assert.assertEquals(current.getUser().getId(), "admin");
|
||||
Authentication
|
||||
.current()
|
||||
.map(Authentication::getUser)
|
||||
.map(User::getId)
|
||||
.subscriberContext(acceptContext(ctx->ctx.put(ContextKey.of(UserToken.class),token)))
|
||||
.as(StepVerifier::create)
|
||||
.expectNext("admin")
|
||||
.verifyComplete();
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user