Browse Source

优化权限控制

zhou-hao 7 years ago
parent
commit
1e5c880fa9
23 changed files with 464 additions and 78 deletions
  1. 2 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/AuthorizationListener.java
  2. 18 7
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/AuthorizationListenerDispatcher.java
  3. 4 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AbstractAuthorizationEvent.java
  4. 1 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationEvent.java
  5. 3 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationExitEvent.java
  6. 3 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationSuccessEvent.java
  7. 116 42
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/DefaultUserTokenManager.java
  8. 25 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/SimpleUserToken.java
  9. 10 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenManager.java
  10. 23 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/event/UserTokenChangedEvent.java
  11. 18 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/event/UserTokenCreatedEvent.java
  12. 5 3
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/event/UserSignInEvent.java
  13. 10 0
      hsweb-authorization/hsweb-authorization-basic/pom.xml
  14. 8 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignIn.java
  15. 11 6
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignOut.java
  16. 3 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/WebUserTokenInterceptor.java
  17. 79 0
      hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/RedisUserTokenManagerTests.java
  18. 45 0
      hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/UserTokenManagerTests.java
  19. 4 0
      hsweb-authorization/hsweb-authorization-cloud/src/main/java/org/hswebframework/web/authorization/cloud/client/feign/FeignUserTokenManager.java
  20. 0 6
      hsweb-examples/hsweb-examples-simple/pom.xml
  21. 1 0
      hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java
  22. 8 9
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/AuthorizationController.java
  23. 67 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/UserTokenController.java

+ 2 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/AuthorizationListener.java

@@ -6,11 +6,13 @@ import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
 
 
 /**
 /**
  * 授权监听器,用于监听授权过程,以及自定义授权逻辑
  * 授权监听器,用于监听授权过程,以及自定义授权逻辑
+ * 已弃用,请使用{@link org.springframework.context.ApplicationListener}
  *
  *
  * @author zhouhao
  * @author zhouhao
  * @see AuthorizationEvent
  * @see AuthorizationEvent
  * @since 3.0
  * @since 3.0
  */
  */
+@Deprecated
 public interface AuthorizationListener<E extends AuthorizationEvent> {
 public interface AuthorizationListener<E extends AuthorizationEvent> {
     void on(E event);
     void on(E event);
 }
 }

+ 18 - 7
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/AuthorizationListenerDispatcher.java

@@ -19,14 +19,22 @@
 package org.hswebframework.web.authorization.listener;
 package org.hswebframework.web.authorization.listener;
 
 
 import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
 import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
 
 
 import java.util.*;
 import java.util.*;
 
 
 /**
 /**
+ * {@link org.springframework.context.ApplicationEventPublisher}
  * @author zhouhao
  * @author zhouhao
  */
  */
+@Deprecated
 public class AuthorizationListenerDispatcher {
 public class AuthorizationListenerDispatcher {
 
 
+    @Autowired
+    private ApplicationEventPublisher eventPublisher;
+
+
     private Map<Class<? extends AuthorizationEvent>, List<AuthorizationListener>> listenerStore = new HashMap<>();
     private Map<Class<? extends AuthorizationEvent>, List<AuthorizationListener>> listenerStore = new HashMap<>();
 
 
     public <E extends AuthorizationEvent> void addListener(Class<E> eventClass, AuthorizationListener<E> listener) {
     public <E extends AuthorizationEvent> void addListener(Class<E> eventClass, AuthorizationListener<E> listener) {
@@ -36,16 +44,19 @@ public class AuthorizationListenerDispatcher {
 
 
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     public <E extends AuthorizationEvent> int doEvent(Class<E> eventType, E event) {
     public <E extends AuthorizationEvent> int doEvent(Class<E> eventType, E event) {
-        List<AuthorizationListener<E>> store = (List) listenerStore.get(eventType);
-        if (null != store) {
-            store.forEach(listener -> listener.on(event));
-            return store.size();
-        }
-        return 0;
+        eventPublisher.publishEvent(event);
+//        List<AuthorizationListener<E>> store = (List) listenerStore.get(eventType);
+//        if (null != store) {
+//            store.forEach(listener -> listener.on(event));
+//            return store.size();
+//        }
+        return 1;
     }
     }
 
 
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     public <E extends AuthorizationEvent> int doEvent(E event) {
     public <E extends AuthorizationEvent> int doEvent(E event) {
-        return doEvent((Class<E>) event.getClass(), event);
+        eventPublisher.publishEvent(event);
+        return 1;
+        //return doEvent((Class<E>) event.getClass(), event);
     }
     }
 }
 }

+ 4 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AbstractAuthorizationEvent.java

@@ -19,6 +19,8 @@
 package org.hswebframework.web.authorization.listener.event;
 package org.hswebframework.web.authorization.listener.event;
 
 
 
 
+import org.springframework.context.ApplicationEvent;
+
 import java.util.Optional;
 import java.util.Optional;
 import java.util.function.Function;
 import java.util.function.Function;
 
 
@@ -28,7 +30,7 @@ import java.util.function.Function;
  * @author zhouhao
  * @author zhouhao
  * @since 3.0
  * @since 3.0
  */
  */
-public abstract class AbstractAuthorizationEvent implements AuthorizationEvent {
+public abstract class AbstractAuthorizationEvent extends ApplicationEvent implements AuthorizationEvent {
     protected String username;
     protected String username;
 
 
     protected String password;
     protected String password;
@@ -43,6 +45,7 @@ public abstract class AbstractAuthorizationEvent implements AuthorizationEvent {
      * @param parameterGetter 参数获取函数,用户获取授权时传入的参数
      * @param parameterGetter 参数获取函数,用户获取授权时传入的参数
      */
      */
     public AbstractAuthorizationEvent(String username, String password, Function<String, Object> parameterGetter) {
     public AbstractAuthorizationEvent(String username, String password, Function<String, Object> parameterGetter) {
+        super(username + "/" + password);
         if (username == null || password == null || parameterGetter == null) {
         if (username == null || password == null || parameterGetter == null) {
             throw new NullPointerException();
             throw new NullPointerException();
         }
         }

+ 1 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationEvent.java

@@ -27,6 +27,7 @@ package org.hswebframework.web.authorization.listener.event;
  * @see AuthorizationBeforeEvent
  * @see AuthorizationBeforeEvent
  * @see AuthorizationDecodeEvent
  * @see AuthorizationDecodeEvent
  * @see AuthorizationExitEvent
  * @see AuthorizationExitEvent
+ * @see org.springframework.context.ApplicationEvent
  * @since 3.0
  * @since 3.0
  */
  */
 public interface AuthorizationEvent {
 public interface AuthorizationEvent {

+ 3 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationExitEvent.java

@@ -19,16 +19,18 @@
 package org.hswebframework.web.authorization.listener.event;
 package org.hswebframework.web.authorization.listener.event;
 
 
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.Authentication;
+import org.springframework.context.ApplicationEvent;
 
 
 /**
 /**
  * 退出登录事件
  * 退出登录事件
  *
  *
  * @author zhouhao
  * @author zhouhao
  */
  */
-public class AuthorizationExitEvent implements AuthorizationEvent {
+public class AuthorizationExitEvent extends ApplicationEvent implements AuthorizationEvent {
     private Authentication authentication;
     private Authentication authentication;
 
 
     public AuthorizationExitEvent(Authentication authentication) {
     public AuthorizationExitEvent(Authentication authentication) {
+        super(authentication);
         this.authentication = authentication;
         this.authentication = authentication;
     }
     }
 
 

+ 3 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/listener/event/AuthorizationSuccessEvent.java

@@ -19,6 +19,7 @@
 package org.hswebframework.web.authorization.listener.event;
 package org.hswebframework.web.authorization.listener.event;
 
 
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.Authentication;
+import org.springframework.context.ApplicationEvent;
 
 
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
@@ -32,7 +33,7 @@ import java.util.function.Function;
  * @see Authentication
  * @see Authentication
  * @since 3.0
  * @since 3.0
  */
  */
-public class AuthorizationSuccessEvent implements AuthorizationEvent {
+public class AuthorizationSuccessEvent extends ApplicationEvent implements AuthorizationEvent {
     private Authentication authentication;
     private Authentication authentication;
 
 
     private Function<String, Object> parameterGetter;
     private Function<String, Object> parameterGetter;
@@ -40,6 +41,7 @@ public class AuthorizationSuccessEvent implements AuthorizationEvent {
     private Map<String, Object> result = new HashMap<>();
     private Map<String, Object> result = new HashMap<>();
 
 
     public AuthorizationSuccessEvent(Authentication authentication, Function<String, Object> parameterGetter) {
     public AuthorizationSuccessEvent(Authentication authentication, Function<String, Object> parameterGetter) {
+        super(authentication);
         this.authentication = authentication;
         this.authentication = authentication;
         this.parameterGetter = parameterGetter;
         this.parameterGetter = parameterGetter;
     }
     }

+ 116 - 42
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/DefaultUserTokenManager.java

@@ -18,12 +18,17 @@
 
 
 package org.hswebframework.web.authorization.token;
 package org.hswebframework.web.authorization.token;
 
 
-import org.hswebframework.web.authorization.listener.AuthorizationListenerDispatcher;
-import org.hswebframework.web.authorization.token.event.UserSignInEvent;
+import org.hswebframework.web.authorization.token.event.UserTokenChangedEvent;
+import org.hswebframework.web.authorization.token.event.UserTokenCreatedEvent;
+import org.hswebframework.web.authorization.token.event.UserTokenRemovedEvent;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
 
 
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 /**
 /**
@@ -36,12 +41,21 @@ public class DefaultUserTokenManager implements UserTokenManager {
 
 
     protected final ConcurrentMap<String, SimpleUserToken> tokenUserStorage;
     protected final ConcurrentMap<String, SimpleUserToken> tokenUserStorage;
 
 
+    protected ConcurrentMap<String, List<String>> userStorage;
+
     public DefaultUserTokenManager() {
     public DefaultUserTokenManager() {
         this(new ConcurrentHashMap<>(256));
         this(new ConcurrentHashMap<>(256));
+
     }
     }
 
 
     public DefaultUserTokenManager(ConcurrentMap<String, SimpleUserToken> storage) {
     public DefaultUserTokenManager(ConcurrentMap<String, SimpleUserToken> storage) {
-        tokenUserStorage = storage;
+        this(storage, new ConcurrentHashMap<>());
+    }
+
+    public DefaultUserTokenManager(ConcurrentMap<String, SimpleUserToken> storage, ConcurrentMap<String, List<String>> userStorage) {
+        this.tokenUserStorage = storage;
+        this.userStorage = userStorage;
+
     }
     }
 
 
     //令牌超时事件,默认3600秒
     //令牌超时事件,默认3600秒
@@ -51,10 +65,11 @@ public class DefaultUserTokenManager implements UserTokenManager {
     private AllopatricLoginMode allopatricLoginMode = AllopatricLoginMode.allow;
     private AllopatricLoginMode allopatricLoginMode = AllopatricLoginMode.allow;
 
 
     //事件转发器
     //事件转发器
-    private AuthorizationListenerDispatcher authorizationListenerDispatcher;
+    private ApplicationEventPublisher eventPublisher;
 
 
-    public void setAuthorizationListenerDispatcher(AuthorizationListenerDispatcher authorizationListenerDispatcher) {
-        this.authorizationListenerDispatcher = authorizationListenerDispatcher;
+    @Autowired(required = false)
+    public void setEventPublisher(ApplicationEventPublisher eventPublisher) {
+        this.eventPublisher = eventPublisher;
     }
     }
 
 
     public void setTimeout(long timeout) {
     public void setTimeout(long timeout) {
@@ -73,6 +88,10 @@ public class DefaultUserTokenManager implements UserTokenManager {
         return allopatricLoginMode;
         return allopatricLoginMode;
     }
     }
 
 
+    protected List<String> getUserToken(String userId) {
+        return userStorage.computeIfAbsent(userId, key -> new ArrayList<>());
+    }
+
     private SimpleUserToken checkTimeout(SimpleUserToken detail) {
     private SimpleUserToken checkTimeout(SimpleUserToken detail) {
         if (null == detail) {
         if (null == detail) {
             return null;
             return null;
@@ -81,7 +100,7 @@ public class DefaultUserTokenManager implements UserTokenManager {
             return detail;
             return detail;
         }
         }
         if (System.currentTimeMillis() - detail.getLastRequestTime() > detail.getMaxInactiveInterval()) {
         if (System.currentTimeMillis() - detail.getLastRequestTime() > detail.getMaxInactiveInterval()) {
-            detail.setState(TokenState.expired);
+            changeTokenState(detail, TokenState.expired);
             return detail;
             return detail;
         }
         }
         return detail;
         return detail;
@@ -94,8 +113,10 @@ public class DefaultUserTokenManager implements UserTokenManager {
 
 
     @Override
     @Override
     public List<UserToken> getByUserId(String userId) {
     public List<UserToken> getByUserId(String userId) {
-        return tokenUserStorage.values().stream()
-                .filter(detail -> detail.getUserId().equals(userId) && checkTimeout(detail) != null)
+        return getUserToken(userId)
+                .stream()
+                .map(tokenUserStorage::get)
+                .filter(Objects::nonNull)
                 .collect(Collectors.toList());
                 .collect(Collectors.toList());
     }
     }
 
 
@@ -111,57 +132,94 @@ public class DefaultUserTokenManager implements UserTokenManager {
 
 
     @Override
     @Override
     public boolean tokenIsLoggedIn(String token) {
     public boolean tokenIsLoggedIn(String token) {
+        UserToken userToken = getByToken(token);
 
 
-        return getByToken(token) != null;
+        return userToken != null && !userToken.isExpired();
     }
     }
 
 
     @Override
     @Override
     public long totalUser() {
     public long totalUser() {
-        return tokenUserStorage.values()
-                .stream()
-                .peek(this::checkTimeout)//检查是否已经超时
-                .filter(UserToken::isEffective)//只返回有效的
-                .map(UserToken::getUserId)
-                .distinct()//去重复
-                .count();
+        return userStorage.size();
+
+//        return tokenUserStorage.values()
+//                .parallelStream()
+//                .peek(this::checkTimeout)//检查是否已经超时
+//                .filter(UserToken::isEffective)//只返回有效的
+//                .map(UserToken::getUserId)
+//                .distinct()//去重复
+//                .count();
     }
     }
 
 
     @Override
     @Override
     public long totalToken() {
     public long totalToken() {
-        return tokenUserStorage.values()
-                .stream()
-                .peek(this::checkTimeout)//检查是否已经超时
-                .filter(UserToken::isEffective)//只返回有效的
-                .count();
+        return tokenUserStorage.size();
+    }
+
+    @Override
+    public void allLoggedUser(Consumer<UserToken> consumer) {
+        tokenUserStorage.values().forEach(consumer);
     }
     }
 
 
     @Override
     @Override
     public List<UserToken> allLoggedUser() {
     public List<UserToken> allLoggedUser() {
-        return tokenUserStorage.values()
-                .stream()
-                .map(this::checkTimeout)
-                .filter(UserToken::isEffective)
-                .collect(Collectors.toList());
+        return new ArrayList<>(tokenUserStorage.values());
     }
     }
 
 
     @Override
     @Override
     public void signOutByUserId(String userId) {
     public void signOutByUserId(String userId) {
-        getByUserId(userId).forEach(detail -> signOutByToken(detail.getToken()));
+        if (null == userId) {
+            return;
+        }
+        List<String> tokens =  getUserToken(userId);
+        tokens.forEach(token->signOutByToken(token,false));
+        tokens.clear();
+        userStorage.remove(userId);
+    }
+
+    private void signOutByToken(String token,boolean removeUserToken) {
+        SimpleUserToken tokenObject = tokenUserStorage.remove(token);
+        if (tokenObject != null) {
+            String userId = tokenObject.getUserId();
+            if(removeUserToken) {
+                List<String> tokens = getUserToken(userId);
+                if (tokens.size() > 0) {
+                    tokens.remove(token);
+                }
+                if (tokens.size() == 0) {
+                    userStorage.remove(tokenObject.getUserId());
+                }
+            }
+            publishEvent(new UserTokenRemovedEvent(tokenObject));
+        }
     }
     }
 
 
     @Override
     @Override
     public void signOutByToken(String token) {
     public void signOutByToken(String token) {
-        tokenUserStorage.remove(token);
+       signOutByToken(token,true);
     }
     }
 
 
-    @Override
-    public void changeTokenState(String token, TokenState state) {
-        SimpleUserToken userToken = getByToken(token);
+    protected void publishEvent(ApplicationEvent event) {
+        if (null != eventPublisher) {
+            eventPublisher.publishEvent(event);
+        }
+    }
+
+    public void changeTokenState(SimpleUserToken userToken, TokenState state) {
         if (null != userToken) {
         if (null != userToken) {
+            SimpleUserToken copy = userToken.copy();
+
             userToken.setState(state);
             userToken.setState(state);
+            syncToken(userToken);
+
+            publishEvent(new UserTokenChangedEvent(copy, userToken));
         }
         }
     }
     }
 
 
+    @Override
+    public void changeTokenState(String token, TokenState state) {
+        changeTokenState(getByToken(token), state);
+    }
+
     @Override
     @Override
     public void changeUserState(String user, TokenState state) {
     public void changeUserState(String user, TokenState state) {
         getByUserId(user).forEach(token -> changeTokenState(token.getToken(), state));
         getByUserId(user).forEach(token -> changeTokenState(token.getToken(), state));
@@ -171,23 +229,25 @@ public class DefaultUserTokenManager implements UserTokenManager {
     public UserToken signIn(String token, String type, String userId, long maxInactiveInterval) {
     public UserToken signIn(String token, String type, String userId, long maxInactiveInterval) {
         SimpleUserToken detail = new SimpleUserToken(userId, token);
         SimpleUserToken detail = new SimpleUserToken(userId, token);
         detail.setType(type);
         detail.setType(type);
-        if (null != authorizationListenerDispatcher) {
-            authorizationListenerDispatcher.doEvent(new UserSignInEvent(detail));
-        }
+        detail.setMaxInactiveInterval(maxInactiveInterval);
+
         if (allopatricLoginMode == AllopatricLoginMode.deny) {
         if (allopatricLoginMode == AllopatricLoginMode.deny) {
-            detail.setState(TokenState.deny);
+            changeTokenState(detail.getToken(), TokenState.deny);
         } else if (allopatricLoginMode == AllopatricLoginMode.offlineOther) {
         } else if (allopatricLoginMode == AllopatricLoginMode.offlineOther) {
             detail.setState(TokenState.effective);
             detail.setState(TokenState.effective);
-            SimpleUserToken oldToken = (SimpleUserToken) getByUserId(userId);
-            if (oldToken != null) {
-                //踢下线
-                oldToken.setState(TokenState.offline);
+            //将已经登录的用户设置为离线
+            List<UserToken> oldToken = getByUserId(userId);
+            for (UserToken userToken : oldToken) {
+                changeTokenState(userToken.getToken(), TokenState.offline);
             }
             }
         } else {
         } else {
             detail.setState(TokenState.effective);
             detail.setState(TokenState.effective);
         }
         }
-        detail.setMaxInactiveInterval(maxInactiveInterval);
         tokenUserStorage.put(token, detail);
         tokenUserStorage.put(token, detail);
+
+        getUserToken(userId).add(token);
+
+        publishEvent(new UserTokenCreatedEvent(detail));
         return detail;
         return detail;
     }
     }
 
 
@@ -196,7 +256,21 @@ public class DefaultUserTokenManager implements UserTokenManager {
         SimpleUserToken userToken = tokenUserStorage.get(token);
         SimpleUserToken userToken = tokenUserStorage.get(token);
         if (null != userToken) {
         if (null != userToken) {
             userToken.touch();
             userToken.touch();
+            syncToken(userToken);
         }
         }
     }
     }
 
 
+    @Override
+    public void checkExpiredToken() {
+        for (SimpleUserToken token : tokenUserStorage.values()) {
+            checkTimeout(token);
+            if (token.isExpired()) {
+                signOutByToken(token.getToken());
+            }
+        }
+    }
+
+    protected void syncToken(UserToken userToken) {
+        //do noting
+    }
 }
 }

+ 25 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/SimpleUserToken.java

@@ -10,6 +10,8 @@ import java.util.concurrent.atomic.AtomicLong;
  */
  */
 public class SimpleUserToken implements UserToken {
 public class SimpleUserToken implements UserToken {
 
 
+    private static final long serialVersionUID = 1L;
+
     private String userId;
     private String userId;
 
 
     private String token;
     private String token;
@@ -112,4 +114,27 @@ public class SimpleUserToken implements UserToken {
     public void setType(String type) {
     public void setType(String type) {
         this.type = type;
         this.type = type;
     }
     }
+
+    public SimpleUserToken copy() {
+        SimpleUserToken userToken = new SimpleUserToken();
+        userToken.firstRequestTime = firstRequestTime;
+        userToken.lastRequestTime = lastRequestTime;
+        userToken.requestTimesCounter = new AtomicLong(requestTimesCounter.get());
+        userToken.token = token;
+        userToken.userId = userId;
+        userToken.state = state;
+        userToken.maxInactiveInterval = maxInactiveInterval;
+        userToken.type = type;
+        return userToken;
+    }
+
+    @Override
+    public int hashCode() {
+        return token.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj != null && hashCode() == obj.hashCode();
+    }
 }
 }

+ 10 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenManager.java

@@ -19,6 +19,7 @@
 package org.hswebframework.web.authorization.token;
 package org.hswebframework.web.authorization.token;
 
 
 import java.util.List;
 import java.util.List;
+import java.util.function.Consumer;
 
 
 /**
 /**
  * 用户授权容器,用来操作所有已经授权的用户
  * 用户授权容器,用来操作所有已经授权的用户
@@ -37,7 +38,7 @@ public interface UserTokenManager {
     UserToken getByToken(String token);
     UserToken getByToken(String token);
 
 
     /**
     /**
-     * 根据用户id,获取全部令牌信息,如果设置了不能跨地点登陆,返回值只可能是{@code null}或者size为1的list
+     * 根据用户id,获取全部令牌信息,如果没有则返回空集合而不是<code>null</code>
      *
      *
      * @param userId 用户id
      * @param userId 用户id
      * @return 授权信息
      * @return 授权信息
@@ -71,6 +72,7 @@ public interface UserTokenManager {
      */
      */
     List<UserToken> allLoggedUser();
     List<UserToken> allLoggedUser();
 
 
+    void allLoggedUser(Consumer<UserToken> consumer);
     /**
     /**
      * 删除用户授权信息
      * 删除用户授权信息
      *
      *
@@ -116,4 +118,11 @@ public interface UserTokenManager {
      * @param token token
      * @param token token
      */
      */
     void touch(String token);
     void touch(String token);
+
+    /**
+     * 检查已过期的token,并将其remove
+     *
+     * @see this#signOutByToken(String)
+     */
+    void checkExpiredToken();
 }
 }

+ 23 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/event/UserTokenChangedEvent.java

@@ -0,0 +1,23 @@
+package org.hswebframework.web.authorization.token.event;
+
+import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
+import org.hswebframework.web.authorization.token.UserToken;
+import org.springframework.context.ApplicationEvent;
+
+public class UserTokenChangedEvent extends ApplicationEvent implements AuthorizationEvent {
+    private UserToken before, after;
+
+    public UserTokenChangedEvent(UserToken before, UserToken after) {
+        super(after);
+        this.before = before;
+        this.after = after;
+    }
+
+    public UserToken getBefore() {
+        return before;
+    }
+
+    public UserToken getAfter() {
+        return after;
+    }
+}

+ 18 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/event/UserTokenCreatedEvent.java

@@ -0,0 +1,18 @@
+package org.hswebframework.web.authorization.token.event;
+
+import org.hswebframework.web.authorization.token.UserToken;
+import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
+import org.springframework.context.ApplicationEvent;
+
+public class UserTokenCreatedEvent extends ApplicationEvent implements AuthorizationEvent {
+    private UserToken detail;
+
+    public UserTokenCreatedEvent(UserToken detail) {
+        super(detail);
+        this.detail = detail;
+    }
+
+    public UserToken getDetail() {
+        return detail;
+    }
+}

+ 5 - 3
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/event/UserSignInEvent.java

@@ -1,12 +1,14 @@
 package org.hswebframework.web.authorization.token.event;
 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.listener.event.AuthorizationEvent;
+import org.hswebframework.web.authorization.token.UserToken;
+import org.springframework.context.ApplicationEvent;
 
 
-public class UserSignInEvent implements AuthorizationEvent {
+public class UserTokenRemovedEvent extends ApplicationEvent implements AuthorizationEvent {
     private UserToken detail;
     private UserToken detail;
 
 
-    public UserSignInEvent(UserToken detail) {
+    public UserTokenRemovedEvent(UserToken token) {
+        super(token);
         this.detail = detail;
         this.detail = detail;
     }
     }
 
 

+ 10 - 0
hsweb-authorization/hsweb-authorization-basic/pom.xml

@@ -55,6 +55,16 @@
             <artifactId>hsweb-commons-entity</artifactId>
             <artifactId>hsweb-commons-entity</artifactId>
             <version>${project.version}</version>
             <version>${project.version}</version>
         </dependency>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     </dependencies>
 
 
 </project>
 </project>

+ 8 - 1
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignIn.java

@@ -6,6 +6,7 @@ import org.hswebframework.web.authorization.token.UserToken;
 import org.hswebframework.web.authorization.token.UserTokenHolder;
 import org.hswebframework.web.authorization.token.UserTokenHolder;
 import org.hswebframework.web.authorization.token.UserTokenManager;
 import org.hswebframework.web.authorization.token.UserTokenManager;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
@@ -13,7 +14,8 @@ import java.util.List;
 /**
 /**
  * @author zhouhao
  * @author zhouhao
  */
  */
-public class UserOnSignIn implements AuthorizationListener<AuthorizationSuccessEvent> {
+public class UserOnSignIn implements AuthorizationListener<AuthorizationSuccessEvent>
+        ,ApplicationListener<AuthorizationSuccessEvent>{
 
 
     private String defaultTokenType = "sessionId";
     private String defaultTokenType = "sessionId";
 
 
@@ -36,6 +38,11 @@ public class UserOnSignIn implements AuthorizationListener<AuthorizationSuccessE
 
 
     @Override
     @Override
     public void on(AuthorizationSuccessEvent event) {
     public void on(AuthorizationSuccessEvent event) {
+       onApplicationEvent(event);
+    }
+
+    @Override
+    public void onApplicationEvent(AuthorizationSuccessEvent event) {
         UserToken token = UserTokenHolder.currentToken();
         UserToken token = UserTokenHolder.currentToken();
         String tokenType = (String) event.getParameter("token_type").orElse(defaultTokenType);
         String tokenType = (String) event.getParameter("token_type").orElse(defaultTokenType);
 
 

+ 11 - 6
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignOut.java

@@ -2,16 +2,16 @@ package org.hswebframework.web.authorization.basic.web;
 
 
 import org.hswebframework.web.authorization.listener.AuthorizationListener;
 import org.hswebframework.web.authorization.listener.AuthorizationListener;
 import org.hswebframework.web.authorization.listener.event.AuthorizationExitEvent;
 import org.hswebframework.web.authorization.listener.event.AuthorizationExitEvent;
+import org.hswebframework.web.authorization.listener.event.AuthorizationSuccessEvent;
 import org.hswebframework.web.authorization.token.UserToken;
 import org.hswebframework.web.authorization.token.UserToken;
 import org.hswebframework.web.authorization.token.UserTokenHolder;
 import org.hswebframework.web.authorization.token.UserTokenHolder;
 import org.hswebframework.web.authorization.token.UserTokenManager;
 import org.hswebframework.web.authorization.token.UserTokenManager;
+import org.springframework.context.ApplicationListener;
 
 
 /**
 /**
- * TODO 完成注释
- *
  * @author zhouhao
  * @author zhouhao
  */
  */
-public class UserOnSignOut implements AuthorizationListener<AuthorizationExitEvent> {
+public class UserOnSignOut implements AuthorizationListener<AuthorizationExitEvent>,ApplicationListener<AuthorizationExitEvent> {
     private UserTokenManager userTokenManager;
     private UserTokenManager userTokenManager;
 
 
     public UserOnSignOut(UserTokenManager userTokenManager) {
     public UserOnSignOut(UserTokenManager userTokenManager) {
@@ -20,11 +20,16 @@ public class UserOnSignOut implements AuthorizationListener<AuthorizationExitEve
 
 
     @Override
     @Override
     public void on(AuthorizationExitEvent event) {
     public void on(AuthorizationExitEvent event) {
-        userTokenManager.signOutByToken(geToken());
+       onApplicationEvent(event);
     }
     }
 
 
-    protected String geToken() {
+    private String geToken() {
         UserToken token = UserTokenHolder.currentToken();
         UserToken token = UserTokenHolder.currentToken();
-        return null != token ? token.getToken() : null;
+        return null != token ? token.getToken() : "";
+    }
+
+    @Override
+    public void onApplicationEvent(AuthorizationExitEvent event) {
+        userTokenManager.signOutByToken(geToken());
     }
     }
 }
 }

+ 3 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/WebUserTokenInterceptor.java

@@ -1,5 +1,7 @@
 package org.hswebframework.web.authorization.basic.web;
 package org.hswebframework.web.authorization.basic.web;
 
 
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
+import org.hswebframework.web.authorization.token.TokenState;
 import org.hswebframework.web.authorization.token.UserToken;
 import org.hswebframework.web.authorization.token.UserToken;
 import org.hswebframework.web.authorization.token.UserTokenHolder;
 import org.hswebframework.web.authorization.token.UserTokenHolder;
 import org.hswebframework.web.authorization.token.UserTokenManager;
 import org.hswebframework.web.authorization.token.UserTokenManager;
@@ -54,4 +56,5 @@ public class WebUserTokenInterceptor extends HandlerInterceptorAdapter {
         }
         }
         return true;
         return true;
     }
     }
+
 }
 }

+ 79 - 0
hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/RedisUserTokenManagerTests.java

@@ -0,0 +1,79 @@
+package org.hswebframework.web.authorization;
+
+import org.hswebframework.web.authorization.token.DefaultUserTokenManager;
+import org.hswebframework.web.authorization.token.SimpleUserToken;
+import org.hswebframework.web.authorization.token.UserToken;
+import org.hswebframework.web.authorization.token.UserTokenManager;
+import org.hswebframework.web.id.IDGenerator;
+import org.junit.Assert;
+import org.redisson.Redisson;
+import org.redisson.api.LocalCachedMapOptions;
+import org.redisson.api.RedissonClient;
+import org.redisson.codec.FstCodec;
+import org.redisson.codec.SerializationCodec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+
+public class RedisUserTokenManagerTests {
+
+    static UserTokenManager userTokenManager;
+
+    static String token = IDGenerator.MD5.generate();
+
+    private static Logger logger = LoggerFactory.getLogger("hsweb.session");
+
+    public static void main(String[] args) throws InterruptedException {
+        RedissonClient client = Redisson.create();
+
+        try {
+            ConcurrentMap<String, SimpleUserToken> repo = client.getMap("hsweb.user-token", new SerializationCodec());
+            ConcurrentMap<String, List<String>> userRepo = client.getMap("hsweb.user-token-u", new SerializationCodec());
+
+            userTokenManager = new DefaultUserTokenManager(repo, userRepo) {
+                @Override
+                protected List<String> getUserToken(String userId) {
+                    userRepo.computeIfAbsent(userId,u->new ArrayList<>());
+
+                    return client.getList("hsweb.user-token-"+userId, new SerializationCodec());
+                }
+
+            };
+//            userTokenManager=new DefaultUserTokenManager();
+
+
+            userRepo.clear();
+            repo.clear();
+            for (int i = 0; i < 1000; i++) {
+                userTokenManager.signIn(IDGenerator.MD5.generate(), "sessionId", "admin", 60*3600*1000);
+            }
+            userTokenManager.signIn(IDGenerator.MD5.generate(), "sessionId", "admin2", 60*3600*1000);
+
+            testGet();
+            testGetAll();
+            testSignOut();
+
+            testGetAll();
+        } finally {
+            client.shutdown();
+        }
+    }
+    public static void testSignOut(){
+        userTokenManager.signOutByUserId("admin");
+
+    }
+    public static void testGet() {
+        List<UserToken> userToken = userTokenManager.getByUserId("admin");
+        Assert.assertTrue(!userToken.isEmpty());
+    }
+
+    public static void testGetAll() {
+        logger.warn("total user : " + userTokenManager.totalUser());
+        logger.warn("total token : " + userTokenManager.totalToken());
+
+        userTokenManager.allLoggedUser(token -> System.out.println(token.getToken()));
+    }
+}

+ 45 - 0
hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/UserTokenManagerTests.java

@@ -0,0 +1,45 @@
+package org.hswebframework.web.authorization;
+
+import org.hswebframework.web.authorization.token.DefaultUserTokenManager;
+import org.hswebframework.web.authorization.token.TokenState;
+import org.hswebframework.web.authorization.token.UserToken;
+import org.hswebframework.web.authorization.token.UserTokenManager;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UserTokenManagerTests {
+
+    protected UserTokenManager userTokenManager = new DefaultUserTokenManager();
+
+
+    public void setUserTokenManager(UserTokenManager userTokenManager) {
+        this.userTokenManager = userTokenManager;
+    }
+
+    @Test
+    public void simpleTest() throws InterruptedException {
+        UserToken userToken = userTokenManager.signIn("test", "sessionId", "admin", 1000);
+
+        Assert.assertNotNull(userToken);
+
+        userTokenManager.changeUserState("admin", TokenState.deny);
+
+        userToken = userTokenManager.getByToken(userToken.getToken());
+
+        Assert.assertEquals(userToken.getState(), TokenState.deny);
+
+        userTokenManager.changeUserState("admin", TokenState.effective);
+
+        Thread.sleep(1200);
+
+        userToken = userTokenManager.getByToken(userToken.getToken());
+        Assert.assertTrue(userToken.isExpired());
+
+        userTokenManager.checkExpiredToken();
+
+        userToken = userTokenManager.getByToken(userToken.getToken());
+        Assert.assertTrue(userToken == null);
+    }
+
+
+}

+ 4 - 0
hsweb-authorization/hsweb-authorization-cloud/src/main/java/org/hswebframework/web/authorization/cloud/client/feign/FeignUserTokenManager.java

@@ -66,4 +66,8 @@ public interface FeignUserTokenManager extends UserTokenManager {
     @Override
     @Override
     @RequestMapping(value = "${hsweb.cloud.user-center.prefix:/}user-token/{token}/touch", method = RequestMethod.GET)
     @RequestMapping(value = "${hsweb.cloud.user-center.prefix:/}user-token/{token}/touch", method = RequestMethod.GET)
     void touch(@PathVariable("token") String token);
     void touch(@PathVariable("token") String token);
+
+    @Override
+    @RequestMapping(value = "${hsweb.cloud.user-center.prefix:/}user-token/check-expired-token", method = RequestMethod.PUT)
+    void checkExpiredToken();
 }
 }

+ 0 - 6
hsweb-examples/hsweb-examples-simple/pom.xml

@@ -108,12 +108,6 @@
             <artifactId>hsweb-system-authorization-starter</artifactId>
             <artifactId>hsweb-system-authorization-starter</artifactId>
             <version>${project.version}</version>
             <version>${project.version}</version>
         </dependency>
         </dependency>
-        <!--使用shiro实现权限控制-->
-        <!--<dependency>-->
-            <!--<groupId>org.hswebframework.web</groupId>-->
-            <!--<artifactId>hsweb-authorization-shiro</artifactId>-->
-            <!--<version>${project.version}</version>-->
-        <!--</dependency>-->
         <!--使用基础权限控制-->
         <!--使用基础权限控制-->
         <dependency>
         <dependency>
             <groupId>org.hswebframework.web</groupId>
             <groupId>org.hswebframework.web</groupId>

+ 1 - 0
hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java

@@ -88,6 +88,7 @@ public class SpringBootExample
     @Bean
     @Bean
     public AopMethodAuthorizeDefinitionCustomizerParser customizerParser(){
     public AopMethodAuthorizeDefinitionCustomizerParser customizerParser(){
         //自定义权限声明
         //自定义权限声明
+        //所有控制都通过
         return context -> EmptyAuthorizeDefinition.instance;
         return context -> EmptyAuthorizeDefinition.instance;
     }
     }
 
 

+ 8 - 9
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/AuthorizationController.java

@@ -35,6 +35,7 @@ import org.hswebframework.web.service.authorization.UserService;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
@@ -61,13 +62,13 @@ public class AuthorizationController {
     private AuthenticationManager authenticationManager;
     private AuthenticationManager authenticationManager;
 
 
     @Autowired
     @Autowired
-    private AuthorizationListenerDispatcher authorizationListenerDispatcher;
+    private ApplicationEventPublisher eventPublisher;
 
 
     @GetMapping({"/login-out", "/sign-out", "/exit"})
     @GetMapping({"/login-out", "/sign-out", "/exit"})
     @Authorize
     @Authorize
     @ApiOperation("退出当前登录")
     @ApiOperation("退出当前登录")
     public ResponseMessage exit(@ApiParam(hidden = true) Authentication authentication) {
     public ResponseMessage exit(@ApiParam(hidden = true) Authentication authentication) {
-        authorizationListenerDispatcher.doEvent(new AuthorizationExitEvent(authentication));
+        eventPublisher.publishEvent(new AuthorizationExitEvent(authentication));
         return ok();
         return ok();
     }
     }
 
 
@@ -88,12 +89,12 @@ public class AuthorizationController {
         Function<String, Object> parameterGetter = request::getParameter;
         Function<String, Object> parameterGetter = request::getParameter;
         try {
         try {
             AuthorizationDecodeEvent decodeEvent = new AuthorizationDecodeEvent(username, password, parameterGetter);
             AuthorizationDecodeEvent decodeEvent = new AuthorizationDecodeEvent(username, password, parameterGetter);
-            authorizationListenerDispatcher.doEvent(decodeEvent);
+            eventPublisher.publishEvent(decodeEvent);
             username = decodeEvent.getUsername();
             username = decodeEvent.getUsername();
             password = decodeEvent.getPassword();
             password = decodeEvent.getPassword();
 
 
             AuthorizationBeforeEvent beforeEvent = new AuthorizationBeforeEvent(username, password, parameterGetter);
             AuthorizationBeforeEvent beforeEvent = new AuthorizationBeforeEvent(username, password, parameterGetter);
-            authorizationListenerDispatcher.doEvent(beforeEvent);
+            eventPublisher.publishEvent(beforeEvent);
             UserEntity entity = userService.selectByUsername(username);
             UserEntity entity = userService.selectByUsername(username);
             if (entity == null) {
             if (entity == null) {
                 reason = AuthorizationFailedEvent.Reason.USER_NOT_EXISTS;
                 reason = AuthorizationFailedEvent.Reason.USER_NOT_EXISTS;
@@ -110,17 +111,15 @@ public class AuthorizationController {
             }
             }
             // 验证通过
             // 验证通过
             Authentication authentication = authenticationManager.getByUserId(entity.getId());
             Authentication authentication = authenticationManager.getByUserId(entity.getId());
+            //触发授权成功事件
             AuthorizationSuccessEvent event = new AuthorizationSuccessEvent(authentication, parameterGetter);
             AuthorizationSuccessEvent event = new AuthorizationSuccessEvent(authentication, parameterGetter);
             event.getResult().put("userId", entity.getId());
             event.getResult().put("userId", entity.getId());
-            int size = authorizationListenerDispatcher.doEvent(event);
-            if (size == 0) {
-                logger.warn("not found any AuthorizationSuccessEvent,access control maybe disabled!");
-            }
+            eventPublisher.publishEvent(event);
             return ok(event.getResult());
             return ok(event.getResult());
         } catch (Exception e) {
         } catch (Exception e) {
             AuthorizationFailedEvent failedEvent = new AuthorizationFailedEvent(username, password, parameterGetter, reason);
             AuthorizationFailedEvent failedEvent = new AuthorizationFailedEvent(username, password, parameterGetter, reason);
             failedEvent.setException(e);
             failedEvent.setException(e);
-            authorizationListenerDispatcher.doEvent(failedEvent);
+            eventPublisher.publishEvent(failedEvent);
             throw e;
             throw e;
         }
         }
     }
     }

+ 67 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/UserTokenController.java

@@ -0,0 +1,67 @@
+package org.hswebframework.web.controller.authorization;
+
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.authorization.token.TokenState;
+import org.hswebframework.web.authorization.token.UserToken;
+import org.hswebframework.web.authorization.token.UserTokenHolder;
+import org.hswebframework.web.authorization.token.UserTokenManager;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.logging.AccessLogger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("${hsweb.web.mappings.user-token:user-token}")
+@AccessLogger("token信息")
+@Authorize(permission = "user-token")
+public class UserTokenController {
+
+    @Autowired
+    private UserTokenManager userTokenManager;
+
+    @GetMapping("/token/total")
+    @Authorize(merge = false)
+    public ResponseMessage<Long> allLoginToken() {
+        return ResponseMessage.ok(userTokenManager.totalToken());
+    }
+
+    @GetMapping("/user/total")
+    @Authorize(merge = false)
+    public ResponseMessage<Long> allUserToken() {
+        return ResponseMessage.ok(userTokenManager.totalUser());
+    }
+
+    @GetMapping("/reset")
+    @Authorize(merge = false)
+    public ResponseMessage<Boolean> resetToken() {
+        UserToken token= UserTokenHolder.currentToken();
+        if(token!=null){
+            userTokenManager.signOutByToken(token.getToken());
+        }
+        return ResponseMessage.ok(true);
+    }
+
+    @GetMapping("/token/all")
+    @Authorize(action = Permission.ACTION_GET)
+    public ResponseMessage<List<UserToken>> allTokenInfo() {
+        return ResponseMessage.ok(userTokenManager.allLoggedUser());
+    }
+
+    @PutMapping("/token/{token}/{state}")
+    @Authorize(action = Permission.ACTION_UPDATE)
+    public ResponseMessage<Void> changeTokenState(@PathVariable String token, @PathVariable TokenState state) {
+        userTokenManager.changeTokenState(token,state);
+
+        return ResponseMessage.ok();
+    }
+    @PutMapping("/user/{userId}/{state}")
+    @Authorize(action = Permission.ACTION_GET)
+    public ResponseMessage<Void> changeUserState(@PathVariable String userId, @PathVariable TokenState state) {
+        userTokenManager.changeUserState(userId,state);
+        return ResponseMessage.ok();
+    }
+
+}