Browse Source

优化OAuth2服务

zhou-hao 7 years ago
parent
commit
746e0c0dda
12 changed files with 58 additions and 15 deletions
  1. 5 0
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/pom.xml
  2. 0 2
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/support/AbstractAuthorizationService.java
  3. 8 2
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/support/client/DefaultClientCredentialGranter.java
  4. 4 0
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/support/refresh/DefaultRefreshTokenGranter.java
  5. 2 2
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/token/AccessTokenService.java
  6. 10 5
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/AccessTokenInfo.java
  7. 0 2
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/request/TokenExpiredCallBack.java
  8. 0 1
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/simple/SimpleOAuth2RequestService.java
  9. 3 0
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/simple/SimpleOAuth2SessionBuilder.java
  10. 1 0
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/simple/request/SimpleOAuth2Request.java
  11. 1 1
      hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/simple/request/SimpleOAuth2Response.java
  12. 24 0
      hsweb-system/hsweb-system-oauth2-server/hsweb-system-oauth2-server-simple/src/main/java/org/hswebframework/web/service/oauth2/server/simple/SimpleAccessTokenService.java

+ 5 - 0
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/pom.xml

@@ -50,6 +50,11 @@
             <artifactId>hsweb-commons-utils</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-concurrent-lock-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 0 - 2
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/support/AbstractAuthorizationService.java

@@ -28,8 +28,6 @@ import org.hswebframework.web.oauth2.core.ErrorType;
 import static org.hswebframework.web.oauth2.core.ErrorType.*;
 
 /**
- * TODO 完成注释
- *
  * @author zhouhao
  */
 public abstract class AbstractAuthorizationService {

+ 8 - 2
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/support/client/DefaultClientCredentialGranter.java

@@ -26,8 +26,6 @@ import org.hswebframework.web.oauth2.core.GrantType;
 import static org.hswebframework.web.oauth2.core.ErrorType.*;
 
 /**
- * TODO 完成注释
- *
  * @author zhouhao
  */
 public class DefaultClientCredentialGranter extends AbstractAuthorizationService implements ClientCredentialGranter {
@@ -51,6 +49,14 @@ public class DefaultClientCredentialGranter extends AbstractAuthorizationService
         accessToken.setClientId(client.getId());
         accessToken.setGrantType(GrantType.client_credentials);
 
+        OAuth2AccessToken old = accessTokenService.tryGetOldToken(accessToken);
+        //如果已存在token并且距离上次更新时间小于10秒
+        if(old!=null&&System.currentTimeMillis()-old.getUpdateTime()<10000){
+
+            return old;
+        }
+
+
         //保存token
         return accessTokenService.saveOrUpdateToken(accessToken);
     }

+ 4 - 0
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/support/refresh/DefaultRefreshTokenGranter.java

@@ -64,6 +64,10 @@ public class DefaultRefreshTokenGranter extends AbstractAuthorizationService imp
         if (System.currentTimeMillis() - accessToken.getCreateTime() > refreshTokenTimeOut) {
             throw new GrantTokenException(EXPIRED_REFRESH_TOKEN);
         }
+        //更新间隔小于10秒 返回原始token
+        if(System.currentTimeMillis()-accessToken.getUpdateTime()<10000){
+            return accessToken;
+        }
         Set<String> newRange = request.getScope() != null ? request.getScope() : accessToken.getScope();
         if (!accessToken.getScope().containsAll(newRange)) {
             throw new GrantTokenException(ErrorType.SCOPE_OUT_OF_RANGE);

+ 2 - 2
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-auth-server/src/main/java/org/hswebframework/web/authorization/oauth2/server/token/AccessTokenService.java

@@ -21,13 +21,13 @@ package org.hswebframework.web.authorization.oauth2.server.token;
 import org.hswebframework.web.authorization.oauth2.server.OAuth2AccessToken;
 
 /**
- * TODO 完成注释
- *
  * @author zhouhao
  */
 public interface AccessTokenService {
     OAuth2AccessToken createToken();
 
+    OAuth2AccessToken tryGetOldToken(OAuth2AccessToken token);
+
     OAuth2AccessToken getTokenByRefreshToken(String refreshToken);
 
     OAuth2AccessToken getTokenByAccessToken(String accessToken);

+ 10 - 5
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/AccessTokenInfo.java

@@ -25,18 +25,18 @@ import com.alibaba.fastjson.annotation.JSONField;
  * @author zhouhao
  */
 public class AccessTokenInfo {
-    private String  id;
+    private String id;
     //授权码
     @JSONField(name = "access_token")
-    private String  accessToken;
+    private String accessToken;
     //更新码
     @JSONField(name = "refresh_token")
-    private String  refreshToken;
+    private String refreshToken;
     //有效期
     @JSONField(name = "expires_in")
     private Integer expiresIn;
     //授权范围
-    private String  scope;
+    private String scope;
 
     private Long createTime;
 
@@ -50,7 +50,12 @@ public class AccessTokenInfo {
     private String serverId;
 
     public boolean isExpire() {
-        return updateTime != null && System.currentTimeMillis() - updateTime > expiresIn * 1000;
+        if (expiresIn == null) {
+            return true;
+        }
+        long time = updateTime==null?createTime:updateTime;
+
+        return System.currentTimeMillis() - time > expiresIn * 1000;
     }
 
     public String getTokenType() {

+ 0 - 2
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/request/TokenExpiredCallBack.java

@@ -19,8 +19,6 @@
 package org.hswebframework.web.authorization.oauth2.client.request;
 
 /**
- * TODO 完成注释
- *
  * @author zhouhao
  */
 public interface TokenExpiredCallBack {

+ 0 - 1
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/simple/SimpleOAuth2RequestService.java

@@ -45,7 +45,6 @@ public class SimpleOAuth2RequestService implements OAuth2RequestService {
 
     private LockManager lockManager;
 
-
     public SimpleOAuth2RequestService(
             OAuth2ServerConfigRepository oAuth2ServerConfigService
             , OAuth2UserTokenRepository oAuth2UserTokenService

+ 3 - 0
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/simple/SimpleOAuth2SessionBuilder.java

@@ -87,6 +87,7 @@ public class SimpleOAuth2SessionBuilder implements OAuth2SessionBuilder {
                 } else {
                     token.setGrantType(grantType);
                     token.setCreateTime(System.currentTimeMillis());
+                    token.setUpdateTime(System.currentTimeMillis());
                     token.setServerId(serverConfig.getId());
                     oAuth2UserTokenRepository.insert(token);
                 }
@@ -123,8 +124,10 @@ public class SimpleOAuth2SessionBuilder implements OAuth2SessionBuilder {
         DefaultOAuth2Session session;
 
         AccessTokenInfo info = tokenGetter.get();
+
         if (null != info) {
             session = new CachedOAuth2Session(info);
+
         } else {
             readWriteLock.writeLock().lock();
             try {

+ 1 - 0
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/simple/request/SimpleOAuth2Request.java

@@ -124,6 +124,7 @@ public class SimpleOAuth2Request implements OAuth2Request {
         if (null != expiredCallBack) {
             //判定token是否过期,过期后先执行回调进行操作如更新token,并尝试重新请求
             auth2Response.judgeError(ErrorType.EXPIRED_TOKEN,() -> {
+
                 //调用回调,并指定重试的操作(重新请求)
                 expiredCallBack.call(() -> createNativeResponse(responseSupplier));
 

+ 1 - 1
hsweb-authorization/hsweb-authorization-oauth2/hsweb-authorization-oauth2-client/src/main/java/org/hswebframework/web/authorization/oauth2/client/simple/request/SimpleOAuth2Response.java

@@ -64,7 +64,7 @@ public class SimpleOAuth2Response implements OAuth2Response {
 
                 if (type == ifError) {
                     //重试后依然是相同的错误,可能是错误类型判断错误或者服务端的问题?
-                    logger.warn("still error [{}], maybe judge error or auth server error! ",ifError);
+                    logger.error("still error [{}], maybe judge error or auth server error! ",ifError);
                 } else {
                     errorType = type;
                 }

+ 24 - 0
hsweb-system/hsweb-system-oauth2-server/hsweb-system-oauth2-server-simple/src/main/java/org/hswebframework/web/service/oauth2/server/simple/SimpleAccessTokenService.java

@@ -23,10 +23,15 @@ import org.hswebframework.web.authorization.oauth2.server.entity.OAuth2AccessEnt
 import org.hswebframework.web.authorization.oauth2.server.OAuth2AccessToken;
 import org.hswebframework.web.authorization.oauth2.server.token.AccessTokenService;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
+import org.hswebframework.web.concurrent.lock.annotation.ReadLock;
+import org.hswebframework.web.concurrent.lock.annotation.WriteLock;
 import org.hswebframework.web.dao.oauth2.OAuth2AccessDao;
 import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.web.service.DefaultDSLQueryService;
 import org.hswebframework.web.service.DefaultDSLUpdateService;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.cache.annotation.Caching;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
@@ -54,6 +59,18 @@ public class SimpleAccessTokenService implements AccessTokenService {
         return this;
     }
 
+    @Override
+    @Cacheable(cacheNames = "oauth2-access-token", key = "'cgo'+#token.clientId+#token.grantType+#token.ownerId")
+    public OAuth2AccessToken tryGetOldToken(OAuth2AccessToken token) {
+        OAuth2AccessToken old = DefaultDSLQueryService
+                .createQuery(oAuth2AccessDao)
+                .where("clientId", token.getClientId())
+                .and("grantType", token.getGrantType())
+                .and("ownerId", token.getOwnerId())
+                .single();
+        return old;
+    }
+
     @Override
     public OAuth2AccessToken createToken() {
         OAuth2AccessEntity accessEntity = entityFactory.newInstance(OAuth2AccessEntity.class);
@@ -65,6 +82,7 @@ public class SimpleAccessTokenService implements AccessTokenService {
 
     @Override
     @Transactional(propagation = Propagation.NOT_SUPPORTED)
+    @Cacheable(cacheNames = "oauth2-access-token", key = "'refresh:'+#refreshToken")
     public OAuth2AccessToken getTokenByRefreshToken(String refreshToken) {
         Assert.notNull(refreshToken, "refreshToken can not be null!");
         return DefaultDSLQueryService.createQuery(oAuth2AccessDao)
@@ -73,6 +91,7 @@ public class SimpleAccessTokenService implements AccessTokenService {
 
     @Override
     @Transactional(propagation = Propagation.NOT_SUPPORTED)
+    @Cacheable(cacheNames = "oauth2-access-token", key = "'token:'+#accessToken")
     public OAuth2AccessToken getTokenByAccessToken(String accessToken) {
         Assert.notNull(accessToken, "accessToken can not be null!");
         return DefaultDSLQueryService.createQuery(oAuth2AccessDao)
@@ -81,6 +100,11 @@ public class SimpleAccessTokenService implements AccessTokenService {
 
     @Override
     @Transactional(propagation = Propagation.NOT_SUPPORTED)
+    @Caching(put = {
+            @CachePut(cacheNames = "oauth2-access-token", key = "'refresh:'+#token.refreshToken"),
+            @CachePut(cacheNames = "oauth2-access-token", key = "'token:'+#token.accessToken"),
+            @CachePut(cacheNames = "oauth2-access-token", key = "'cgo'+#token.clientId+#token.grantType+#token.ownerId")
+    })
     public OAuth2AccessToken saveOrUpdateToken(OAuth2AccessToken token) {
         Assert.notNull(token, "token can not be null!");
         int total = DefaultDSLQueryService