Bladeren bron

优化授权容器

zhouhao 7 jaren geleden
bovenliggende
commit
c427d2afc3

+ 34 - 15
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/container/AuthenticationContainer.java

@@ -18,9 +18,6 @@
 
 package org.hswebframework.web.authorization.container;
 
-import org.hswebframework.web.authorization.Authentication;
-
-import javax.servlet.http.HttpSession;
 import java.util.List;
 
 /**
@@ -32,40 +29,62 @@ import java.util.List;
 public interface AuthenticationContainer {
 
     /**
-     * 根据sessionId获取权限信息
+     * 根据token获取权限信息
      *
-     * @param sessionId
+     * @param token
      * @return 权限信息, 未授权时返回null
      */
-    Authentication getAuthenticationBySessionId(String sessionId);
+    UserToken getByToken(String token);
+
+    /**
+     * 根据用户id,获取全部授权信息,如果设置了不能跨地点登陆,返回值只可能是{@code null}或者size为1的list
+     * @param userId 用户id
+     * @return 授权信息
+     */
+    List<UserToken> getByUserId(String userId);
 
     /**
      * @param userId 用户ID
      * @return 用户是否已经授权
      */
-    boolean userIsAuthorized(String userId);
+    boolean userIsLoggedIn(String userId);
+
+    boolean tokenIsLoggedIn(String token);
 
     /**
-     * @return 已经授权的总人数
+     * @return 总用户数量,一个用户多个地方登陆数量算1
      */
-    int totalAuthorizedUser();
+    int totalUser();
 
+    /**
+     *
+     * @return 总token数量
+     */
+    int totalToken();
     /**
      * @return 所有被授权的用户
      */
-    List<Authentication> allAuthorizedUser();
+    List<UserToken> allLoggedUser();
 
     /**
      * 删除用户授权信息
      *
      * @param userId 用户ID
-     * @return 被删除的权限信息
      */
-    Authentication removeAuthentication(String userId);
+    void logoutByUserId(String userId);
+
+    /**
+     * 根据token删除
+     * @param token
+     */
+    void logoutByToken(String token);
 
     /**
-     * @param authentication
-     * @return 添加后被覆盖的权限信息 ,如果没有则返回null
+     * @param token
+     * @param userId
      */
-    Authentication addAuthentication(Authentication authentication, String sessionId);
+    UserToken signIn(String token, String userId);
+
+
+    void touch(String token);
 }

+ 139 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/container/MemeoryAuthenticationContainer.java

@@ -0,0 +1,139 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.authorization.container;
+
+import org.hswebframework.web.authorization.AuthenticationManager;
+import org.hswebframework.web.authorization.container.event.UserSignInEvent;
+import org.hswebframework.web.authorization.listener.AuthorizationListenerDispatcher;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.stream.Collectors;
+
+/**
+ * 授权容器,用来操作所有已经授权的用户
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public class MemeoryAuthenticationContainer implements AuthenticationContainer {
+
+    private ConcurrentMap<String, SimpleUserToken> tokenUserStorage = new ConcurrentHashMap<>(256);
+
+    private AuthenticationManager authenticationManager;
+
+    // timeout seconds
+    private long timeout = 3600;
+
+    private AuthorizationListenerDispatcher authorizationListenerDispatcher;
+
+    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
+        this.authenticationManager = authenticationManager;
+    }
+
+    public void setAuthorizationListenerDispatcher(AuthorizationListenerDispatcher authorizationListenerDispatcher) {
+        this.authorizationListenerDispatcher = authorizationListenerDispatcher;
+    }
+
+    public void setTimeout(long timeout) {
+        this.timeout = timeout;
+    }
+
+    public long getTimeout() {
+        return timeout;
+    }
+
+    private UserToken checkTimeout(UserToken detail) {
+        if (null == detail) return null;
+        if (System.currentTimeMillis() - detail.getLastRequestTime() > timeout * 1000) {
+            logoutByToken(detail.getToken());
+            return null;
+        }
+        return detail;
+    }
+
+    @Override
+    public UserToken getByToken(String token) {
+        return checkTimeout(tokenUserStorage.get(token));
+    }
+
+    @Override
+    public List<UserToken> getByUserId(String userId) {
+        return tokenUserStorage.values().stream()
+                .filter(detail -> detail.getUserId().equals(userId) && checkTimeout(detail) != null)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public boolean userIsLoggedIn(String userId) {
+        return getByUserId(userId).size() > 0;
+    }
+
+    @Override
+    public boolean tokenIsLoggedIn(String token) {
+        return getByToken(token) != null;
+    }
+
+    @Override
+    public int totalUser() {
+        return tokenUserStorage.values().stream().map(UserToken::getUserId).distinct().mapToInt(userId->1).sum();
+    }
+
+    @Override
+    public int totalToken() {
+        return tokenUserStorage.size();
+    }
+
+    @Override
+    public List<UserToken> allLoggedUser() {
+        return tokenUserStorage.values().stream()
+                .map(this::checkTimeout)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public void logoutByUserId(String userId) {
+        getByUserId(userId).forEach(detail -> logoutByToken(detail.getToken()));
+    }
+
+    @Override
+    public void logoutByToken(String token) {
+        tokenUserStorage.remove(token);
+    }
+
+    @Override
+    public UserToken signIn(String token, String userId) {
+        SimpleUserToken detail = new SimpleUserToken(userId, token);
+        if (null != authorizationListenerDispatcher)
+            authorizationListenerDispatcher.doEvent(new UserSignInEvent(detail));
+        tokenUserStorage.put(token, detail);
+        return detail;
+    }
+
+    @Override
+    public void touch(String token) {
+        SimpleUserToken detail = tokenUserStorage.get(token);
+        if (null != detail)
+            detail.touch();
+    }
+}

+ 80 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/container/SimpleUserToken.java

@@ -0,0 +1,80 @@
+package org.hswebframework.web.authorization.container;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Created by zhouhao on 2017/7/7.
+ */
+public class SimpleUserToken implements UserToken {
+
+    private String userId;
+
+    private String token;
+
+    private AtomicLong requestTimesCounter=new AtomicLong(0);
+
+    private volatile long lastRequestTime=System.currentTimeMillis();
+
+    private volatile long firstRequestTime=System.currentTimeMillis();
+
+    private long requestTimes;
+
+    public SimpleUserToken(String userId, String token) {
+        this.userId = userId;
+        this.token = token;
+    }
+
+    public SimpleUserToken() {
+    }
+
+    @Override
+    public String getUserId() {
+        return userId;
+    }
+
+    @Override
+    public long getRequestTimes() {
+        return requestTimesCounter.get();
+    }
+
+    @Override
+    public long getLastRequestTime() {
+        return lastRequestTime;
+    }
+
+    @Override
+    public long getSignInTime() {
+        return firstRequestTime;
+    }
+
+    @Override
+    public String getToken() {
+        return token;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public void setFirstRequestTime(long firstRequestTime) {
+        this.firstRequestTime = firstRequestTime;
+    }
+
+    public void setLastRequestTime(long lastRequestTime) {
+        this.lastRequestTime = lastRequestTime;
+    }
+
+    public void setRequestTimes(long requestTimes) {
+        this.requestTimes = requestTimes;
+        requestTimesCounter.set(requestTimes);
+    }
+
+    public  synchronized void touch(){
+        requestTimesCounter.addAndGet(1);
+        lastRequestTime=System.currentTimeMillis();
+    }
+}

+ 24 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/container/UserToken.java

@@ -0,0 +1,24 @@
+package org.hswebframework.web.authorization.container;
+
+
+import java.io.Serializable;
+
+/**
+ * Created by zhouhao on 2017/7/7.
+ */
+public interface UserToken extends Serializable, Comparable<UserToken> {
+    String getUserId();
+
+    String getToken();
+
+    long getRequestTimes();
+
+    long getLastRequestTime();
+
+    long getSignInTime();
+
+    @Override
+    default int compareTo(UserToken o) {
+        return Long.valueOf(getSignInTime()).compareTo(o.getSignInTime());
+    }
+}

+ 20 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/container/event/UserSignInEvent.java

@@ -0,0 +1,20 @@
+package org.hswebframework.web.authorization.container.event;
+
+import org.hswebframework.web.authorization.container.UserToken;
+import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
+
+/**
+ * Created by zhouhao on 2017/7/7.
+ */
+public class UserSignInEvent implements AuthorizationEvent {
+    private UserToken detail;
+
+
+    public UserSignInEvent(UserToken detail) {
+        this.detail = detail;
+    }
+
+    public UserToken getDetail() {
+        return detail;
+    }
+}