Spring OAuth2为令牌端点的每个请求生成访问令牌

是否可以使用每个请求的client_credentials或密码授予类型生成多个有效的访问令牌?

使用上述授权类型生成令牌仅在当前请求到期时提供新令牌。

我可以使用密码授予类型生成刷新令牌,然后生成多个访问令牌,但这样做会使以前的任何访问令牌无效。

我知道如何更改以允许每次请求生成访问令牌到/ oauth / token端点并确保任何以前的令牌都不会失效?

下面是我的oauth服务器的XML配置。

                                                     

更新于21/11/2014

当我仔细检查时,我发现InMemoryTokenStore使用OAuth2Authentication的哈希字符串作为OAuth2Authentication Map键。 当我使用相同的用户名,client_id,范围..并且我得到相同的key 。 所以这可能会导致一些问题。 所以我认为旧的方式已被弃用。 以下是我为避免此问题所做的工作。

创建另一个可以计算唯一键的AuthenticationKeyGenerator ,名为UniqueAuthenticationKeyGenerator

 /* * Copyright 2006-2011 the original author or authors. * * 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. */ /** * Basic key generator taking into account the client id, scope, resource ids and username (principal name) if they * exist. * * @author Dave Syer * @author thanh */ public class UniqueAuthenticationKeyGenerator implements AuthenticationKeyGenerator { private static final String CLIENT_ID = "client_id"; private static final String SCOPE = "scope"; private static final String USERNAME = "username"; private static final String UUID_KEY = "uuid"; public String extractKey(OAuth2Authentication authentication) { Map values = new LinkedHashMap(); OAuth2Request authorizationRequest = authentication.getOAuth2Request(); if (!authentication.isClientOnly()) { values.put(USERNAME, authentication.getName()); } values.put(CLIENT_ID, authorizationRequest.getClientId()); if (authorizationRequest.getScope() != null) { values.put(SCOPE, OAuth2Utils.formatParameterList(authorizationRequest.getScope())); } Map extentions = authorizationRequest.getExtensions(); String uuid = null; if (extentions == null) { extentions = new HashMap(1); uuid = UUID.randomUUID().toString(); extentions.put(UUID_KEY, uuid); } else { uuid = (String) extentions.get(UUID_KEY); if (uuid == null) { uuid = UUID.randomUUID().toString(); extentions.put(UUID_KEY, uuid); } } values.put(UUID_KEY, uuid); MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("MD5 algorithm not available. Fatal (should be in the JDK)."); } try { byte[] bytes = digest.digest(values.toString().getBytes("UTF-8")); return String.format("%032x", new BigInteger(1, bytes)); } catch (UnsupportedEncodingException e) { throw new IllegalStateException("UTF-8 encoding not available. Fatal (should be in the JDK)."); } } } 

最后,将它们连接起来

       

以下方式可能会导致一些问题,请参阅更新的答案!!!

您正在使用DefaultTokenServices。 试试这段代码,确保重新定义你的`tokenServices`包com.thanh.backend.oauth2.core; import java.util.Date; import java.util.UUID; import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.security.oauth2.provider.token.TokenStore; / ** * @author thanh * / public class SimpleTokenService扩展DefaultTokenServices {private TokenStore tokenStore; private TokenEnhancer accessTokenEnhancer; @Override public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication)抛出AuthenticationException {OAuth2RefreshToken refreshToken = createRefreshToken(authentication);; OAuth2AccessToken accessToken = createAccessToken(authentication,refreshToken); tokenStore.storeAccessToken(accessToken,authentication); tokenStore.storeRefreshToken(refreshToken,authentication); return accessToken; } private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication,OAuth2RefreshToken refreshToken){DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID()。toString()); int validitySeconds = getAccessTokenValiditySeconds(authentication.getOAuth2Request()); if(validitySeconds> 0){token.setExpiration(new Date(System.currentTimeMillis()+(validitySeconds * 1000L))); } token.setRefreshToken(refreshToken); token.setScope(authentication.getOAuth2Request()getScope()); return accessTokenEnhancer!= null? accessTokenEnhancer.enhance(token,authentication):token; } private ExpiringOAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication){if(!isSupportRefreshToken(authentication.getOAuth2Request())){return null; } int validitySeconds = getRefreshTokenValiditySeconds(authentication.getOAuth2Request()); ExpiringOAuth2RefreshToken refreshToken = new DefaultExpiringOAuth2RefreshToken(UUID.randomUUID()。toString(),new Date(System.currentTimeMillis()+(validitySeconds * 1000L))); return refreshToken; } @Override public void setTokenEnhancer(TokenEnhancer accessTokenEnhancer){super.setTokenEnhancer(accessTokenEnhancer); this.accessTokenEnhancer = accessTokenEnhancer; } @Override public void setTokenStore(TokenStore tokenStore){super.setTokenStore(tokenStore); this.tokenStore = tokenStore; }}