diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenRegistration.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenRegistration.java index b2641fc..8f844a0 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenRegistration.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenRegistration.java @@ -31,7 +31,6 @@ public class AccessTokenRegistration { private String grantType; private UserSubject subject; private String audience; - private String clientCodeVerifier; /** * Sets the {@link Client} instance @@ -121,13 +120,5 @@ public class AccessTokenRegistration { public void setAudience(String audience) { this.audience = audience; } - - public String getClientCodeVerifier() { - return clientCodeVerifier; - } - - public void setClientCodeVerifier(String clientCodeVerifier) { - this.clientCodeVerifier = clientCodeVerifier; - } } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java index f25f286..3455a21 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java @@ -48,7 +48,6 @@ public class AccessTokenValidation { private UserSubject tokenSubject; private List tokenScopes = new LinkedList(); private String audience; - private String clientCodeVerifier; private Map extraProps = new HashMap(); public AccessTokenValidation() { @@ -69,7 +68,6 @@ public class AccessTokenValidation { this.tokenSubject = token.getSubject(); this.tokenScopes = token.getScopes(); this.audience = token.getAudience(); - this.clientCodeVerifier = token.getClientCodeVerifier(); } public String getClientId() { @@ -160,12 +158,5 @@ public class AccessTokenValidation { public void setClientConfidential(boolean isConfidential) { this.isClientConfidential = isConfidential; } - public String getClientCodeVerifier() { - return clientCodeVerifier; - } - - public void setClientCodeVerifier(String clientCodeVerifier) { - this.clientCodeVerifier = clientCodeVerifier; - } } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ServerAccessToken.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ServerAccessToken.java index d5cc449..965b758 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ServerAccessToken.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ServerAccessToken.java @@ -36,7 +36,6 @@ public abstract class ServerAccessToken extends AccessToken { private List scopes = new LinkedList(); private UserSubject subject; private String audience; - private String clientCodeVerifier; protected ServerAccessToken() { @@ -150,12 +149,4 @@ public abstract class ServerAccessToken extends AccessToken { } return token; } - - public String getClientCodeVerifier() { - return clientCodeVerifier; - } - - public void setClientCodeVerifier(String clientCodeVerifier) { - this.clientCodeVerifier = clientCodeVerifier; - } } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/AbstractGrantHandler.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/AbstractGrantHandler.java index f1b2a0a..58d0bda 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/AbstractGrantHandler.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/AbstractGrantHandler.java @@ -84,7 +84,7 @@ public abstract class AbstractGrantHandler implements AccessTokenGrantHandler { } } - protected String getSingleGrantType() { + private String getSingleGrantType() { if (supportedGrants.size() > 1) { String errorMessage = "Request grant type must be specified"; LOG.warning(errorMessage); @@ -100,7 +100,6 @@ public abstract class AbstractGrantHandler implements AccessTokenGrantHandler { return doCreateAccessToken(client, subject, OAuthUtils.parseScope(params.getFirst(OAuthConstants.SCOPE)), - null, params.getFirst(OAuthConstants.CLIENT_AUDIENCE)); } @@ -108,34 +107,29 @@ public abstract class AbstractGrantHandler implements AccessTokenGrantHandler { UserSubject subject, List requestedScope) { - return doCreateAccessToken(client, subject, getSingleGrantType(), requestedScope, - null, null, null); + return doCreateAccessToken(client, subject, getSingleGrantType(), requestedScope, null); } protected ServerAccessToken doCreateAccessToken(Client client, UserSubject subject, List requestedScope, - List approvedScope, String audience) { - return doCreateAccessToken(client, subject, getSingleGrantType(), requestedScope, - approvedScope, audience, null); + return doCreateAccessToken(client, subject, getSingleGrantType(), requestedScope, audience); } protected ServerAccessToken doCreateAccessToken(Client client, UserSubject subject, String requestedGrant, List requestedScope) { - return doCreateAccessToken(client, subject, requestedGrant, requestedScope, null, null, null); + return doCreateAccessToken(client, subject, requestedGrant, requestedScope, null); } protected ServerAccessToken doCreateAccessToken(Client client, UserSubject subject, String requestedGrant, List requestedScope, - List approvedScope, - String audience, - String codeVerifier) { + String audience) { if (!OAuthUtils.validateScopes(requestedScope, client.getRegisteredScopes(), partialMatchScopeValidation)) { throw new OAuthServiceException(new OAuthError(OAuthConstants.INVALID_SCOPE)); @@ -156,13 +150,8 @@ public abstract class AbstractGrantHandler implements AccessTokenGrantHandler { reg.setClient(client); reg.setGrantType(requestedGrant); reg.setSubject(subject); - reg.setRequestedScope(requestedScope); - if (approvedScope == null) { - approvedScope = Collections.emptyList(); - } - reg.setApprovedScope(approvedScope); + reg.setRequestedScope(requestedScope); reg.setAudience(audience); - reg.setClientCodeVerifier(codeVerifier); return dataProvider.createAccessToken(reg); } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AuthorizationCodeGrantHandler.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AuthorizationCodeGrantHandler.java index 9a6888a..7e6972f 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AuthorizationCodeGrantHandler.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AuthorizationCodeGrantHandler.java @@ -35,7 +35,6 @@ import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; public class AuthorizationCodeGrantHandler extends AbstractGrantHandler { private CodeVerifierTransformer codeVerifierTransformer; - private boolean expectCodeVerifierForPublicClients; public AuthorizationCodeGrantHandler() { super(OAuthConstants.AUTHORIZATION_CODE_GRANT); @@ -72,41 +71,31 @@ public class AuthorizationCodeGrantHandler extends AbstractGrantHandler { throw new OAuthServiceException(OAuthConstants.INVALID_REQUEST); } - String clientCodeVerifier = params.getFirst(OAuthConstants.AUTHORIZATION_CODE_VERIFIER); String clientCodeChallenge = grant.getClientCodeChallenge(); - if (!compareCodeVerifierWithChallenge(client, clientCodeVerifier, clientCodeChallenge)) { - throw new OAuthServiceException(OAuthConstants.INVALID_GRANT); + if (clientCodeChallenge != null) { + String clientCodeVerifier = params.getFirst(OAuthConstants.AUTHORIZATION_CODE_VERIFIER); + if (!compareCodeVerifierWithChallenge(clientCodeVerifier, clientCodeChallenge)) { + throw new OAuthServiceException(OAuthConstants.INVALID_GRANT); + } } return doCreateAccessToken(client, grant.getSubject(), - getSingleGrantType(), - grant.getRequestedScopes(), grant.getApprovedScopes(), - grant.getAudience(), - clientCodeVerifier); + grant.getAudience()); } - private boolean compareCodeVerifierWithChallenge(Client c, String clientCodeVerifier, - String clientCodeChallenge) { - if (clientCodeChallenge == null && clientCodeChallenge == null - && (c.isConfidential() || !expectCodeVerifierForPublicClients)) { - return true; - } else if (clientCodeChallenge != null && clientCodeChallenge == null - || clientCodeChallenge == null && clientCodeChallenge != null) { + private boolean compareCodeVerifierWithChallenge(String clientCodeVerifier, String clientCodeChallenge) { + if (clientCodeChallenge == null) { return false; - } else { - String transformedCodeVerifier = codeVerifierTransformer == null - ? clientCodeVerifier : codeVerifierTransformer.transformCodeVerifier(clientCodeVerifier); - return clientCodeChallenge.equals(transformedCodeVerifier); } + String transformedCodeVerifier = codeVerifierTransformer == null + ? clientCodeVerifier : codeVerifierTransformer.transformCodeVerifier(clientCodeVerifier); + return clientCodeChallenge.equals(transformedCodeVerifier); + } public void setCodeVerifierTransformer(CodeVerifierTransformer codeVerifier) { this.codeVerifierTransformer = codeVerifier; } - - public void setExpectCodeVerifierForPublicClients(boolean expectCodeVerifierForPublicClients) { - this.expectCodeVerifierForPublicClients = expectCodeVerifierForPublicClients; - } } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEHCacheCodeDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEHCacheCodeDataProvider.java index da242aa..d148423 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEHCacheCodeDataProvider.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEHCacheCodeDataProvider.java @@ -18,18 +18,14 @@ */ package org.apache.cxf.rs.security.oauth2.grants.code; -import java.util.ArrayList; import java.util.List; import net.sf.ehcache.Ehcache; import org.apache.cxf.Bus; -import org.apache.cxf.helpers.CastUtils; -import org.apache.cxf.rs.security.oauth2.common.Client; -import org.apache.cxf.rs.security.oauth2.provider.AbstractCodeDataProvider; import org.apache.cxf.rs.security.oauth2.provider.DefaultEHCacheOAuthDataProvider; import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; - +import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; public class DefaultEHCacheCodeDataProvider extends DefaultEHCacheOAuthDataProvider implements AuthorizationCodeDataProvider { @@ -58,63 +54,55 @@ public class DefaultEHCacheCodeDataProvider extends DefaultEHCacheOAuthDataProvi } @Override - public Client removeClient(String clientId) { - Client c = super.removeClient(clientId); - removeClientCodeGrants(c); - return c; - } - - protected void removeClientCodeGrants(Client c) { - for (ServerAuthorizationCodeGrant grant : getCodeGrants(c)) { - removeCodeGrant(grant.getCode()); - } - } - - @Override public ServerAuthorizationCodeGrant createCodeGrant(AuthorizationCodeRegistration reg) throws OAuthServiceException { ServerAuthorizationCodeGrant grant = doCreateCodeGrant(reg); - saveCodeGrant(grant); + saveAuthorizationGrant(grant); return grant; } - - protected ServerAuthorizationCodeGrant doCreateCodeGrant(AuthorizationCodeRegistration reg) - throws OAuthServiceException { - return AbstractCodeDataProvider.initCodeGrant(reg, grantLifetime); - } - public List getCodeGrants(Client c) { - List keys = CastUtils.cast(codeGrantCache.getKeys()); - List grants = - new ArrayList(keys.size()); - for (String key : keys) { - ServerAuthorizationCodeGrant grant = getCodeGrant(key); - if (grant.getClient().getClientId().equals(c.getClientId())) { - grants.add(grant); - } - } - return grants; - } - @Override public ServerAuthorizationCodeGrant removeCodeGrant(String code) throws OAuthServiceException { - ServerAuthorizationCodeGrant grant = getCodeGrant(code); + ServerAuthorizationCodeGrant grant = getCacheValue(codeGrantCache, + code, + ServerAuthorizationCodeGrant.class); if (grant != null) { codeGrantCache.remove(code); } return grant; } - public ServerAuthorizationCodeGrant getCodeGrant(String code) throws OAuthServiceException { - return getCacheValue(codeGrantCache, - code, - ServerAuthorizationCodeGrant.class); + protected ServerAuthorizationCodeGrant doCreateCodeGrant(AuthorizationCodeRegistration reg) + throws OAuthServiceException { + ServerAuthorizationCodeGrant grant = + new ServerAuthorizationCodeGrant(reg.getClient(), getCode(reg), getGrantLifetime(), getIssuedAt()); + grant.setApprovedScopes(getApprovedScopes(reg)); + grant.setAudience(reg.getAudience()); + grant.setClientCodeChallenge(reg.getClientCodeChallenge()); + grant.setSubject(reg.getSubject()); + grant.setRedirectUri(reg.getRedirectUri()); + return grant; } - - protected void saveCodeGrant(ServerAuthorizationCodeGrant grant) { - putCacheValue(codeGrantCache, grant.getCode(), grant, grant.getExpiresIn()); + + protected List getApprovedScopes(AuthorizationCodeRegistration reg) { + return reg.getApprovedScope(); + } + + protected String getCode(AuthorizationCodeRegistration reg) { + return OAuthUtils.generateRandomTokenKey(); + } + + public long getGrantLifetime() { + return grantLifetime; } + public void setGrantLifetime(long lifetime) { + this.grantLifetime = lifetime; + } + + protected long getIssuedAt() { + return OAuthUtils.getIssuedAt(); + } protected void saveAuthorizationGrant(ServerAuthorizationCodeGrant grant) { putCacheValue(codeGrantCache, grant.getCode(), grant, grant.getExpiresIn()); diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEncryptingCodeDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEncryptingCodeDataProvider.java index d497c0f..64e6276 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEncryptingCodeDataProvider.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEncryptingCodeDataProvider.java @@ -18,7 +18,6 @@ */ package org.apache.cxf.rs.security.oauth2.grants.code; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -27,7 +26,6 @@ import java.util.Set; import javax.crypto.SecretKey; import org.apache.cxf.common.util.crypto.KeyProperties; -import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.provider.DefaultEncryptingOAuthDataProvider; import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; @@ -47,18 +45,6 @@ public class DefaultEncryptingCodeDataProvider extends DefaultEncryptingOAuthDat super(key); } @Override - public Client removeClient(String clientId) { - Client c = super.removeClient(clientId); - removeClientCodeGrants(c); - return c; - } - - protected void removeClientCodeGrants(Client c) { - for (ServerAuthorizationCodeGrant grant : getCodeGrants(c)) { - removeCodeGrant(grant.getCode()); - } - } - @Override public ServerAuthorizationCodeGrant createCodeGrant(AuthorizationCodeRegistration reg) throws OAuthServiceException { ServerAuthorizationCodeGrant grant = doCreateCodeGrant(reg); @@ -66,31 +52,11 @@ public class DefaultEncryptingCodeDataProvider extends DefaultEncryptingOAuthDat return grant; } - public List getCodeGrants(Client c) { - List list = - new ArrayList(grants.size()); - for (String key : grants) { - ServerAuthorizationCodeGrant grant = getCodeGrant(key); - if (grant.getClient().getClientId().equals(c.getClientId())) { - list.add(grant); - } - } - return list; - } - @Override public ServerAuthorizationCodeGrant removeCodeGrant(String code) throws OAuthServiceException { grants.remove(code); return ModelEncryptionSupport.decryptCodeGrant(this, code, key); } - public ServerAuthorizationCodeGrant getCodeGrant(String code) throws OAuthServiceException { - - ServerAuthorizationCodeGrant grant = ModelEncryptionSupport.decryptCodeGrant(this, code, key); - if (grant != null) { - grants.remove(code); - } - return grant; - } protected ServerAuthorizationCodeGrant doCreateCodeGrant(AuthorizationCodeRegistration reg) throws OAuthServiceException { diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/ServerAuthorizationCodeGrant.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/ServerAuthorizationCodeGrant.java index a1aba9f..b2b3835 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/ServerAuthorizationCodeGrant.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/ServerAuthorizationCodeGrant.java @@ -36,7 +36,6 @@ public class ServerAuthorizationCodeGrant extends AuthorizationCodeGrant { private long expiresIn; private Client client; private List approvedScopes = Collections.emptyList(); - private List requestedScopes = Collections.emptyList(); private UserSubject subject; private String audience; private String clientCodeChallenge; @@ -157,12 +156,4 @@ public class ServerAuthorizationCodeGrant extends AuthorizationCodeGrant { public void setClientCodeChallenge(String clientCodeChallenge) { this.clientCodeChallenge = clientCodeChallenge; } - - public List getRequestedScopes() { - return requestedScopes; - } - - public void setRequestedScopes(List requestedScopes) { - this.requestedScopes = requestedScopes; - } } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractCodeDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractCodeDataProvider.java deleted file mode 100644 index 46dd951..0000000 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractCodeDataProvider.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.cxf.rs.security.oauth2.provider; - -import java.util.List; - -import org.apache.cxf.rs.security.oauth2.common.Client; -import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeDataProvider; -import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeRegistration; -import org.apache.cxf.rs.security.oauth2.grants.code.ServerAuthorizationCodeGrant; - -public abstract class AbstractCodeDataProvider extends AbstractOAuthDataProvider - implements AuthorizationCodeDataProvider { - private long codeLifetime = 3600L; - - protected AbstractCodeDataProvider() { - } - - @Override - public ServerAuthorizationCodeGrant createCodeGrant(AuthorizationCodeRegistration reg) - throws OAuthServiceException { - ServerAuthorizationCodeGrant grant = doCreateCodeGrant(reg); - saveCodeGrant(grant); - return grant; - } - - protected ServerAuthorizationCodeGrant doCreateCodeGrant(AuthorizationCodeRegistration reg) - throws OAuthServiceException { - return AbstractCodeDataProvider.initCodeGrant(reg, codeLifetime); - } - - public void setCodeLifetime(long codeLifetime) { - this.codeLifetime = codeLifetime; - } - - public static ServerAuthorizationCodeGrant initCodeGrant(AuthorizationCodeRegistration reg, - long lifetime) { - ServerAuthorizationCodeGrant grant = new ServerAuthorizationCodeGrant(reg.getClient(), lifetime); - grant.setRedirectUri(reg.getRedirectUri()); - grant.setSubject(reg.getSubject()); - grant.setRequestedScopes(reg.getRequestedScope()); - grant.setApprovedScopes(reg.getApprovedScope()); - grant.setAudience(reg.getAudience()); - grant.setClientCodeChallenge(reg.getClientCodeChallenge()); - return grant; - } - - protected void removeClientCodeGrants(Client c) { - for (ServerAuthorizationCodeGrant grant : getCodeGrants(c)) { - removeCodeGrant(grant.getCode()); - } - } - - protected abstract void saveCodeGrant(ServerAuthorizationCodeGrant grant); - public abstract List getCodeGrants(Client c); - -} diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java index 391a8aa..7494d74 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java @@ -18,13 +18,9 @@ */ package org.apache.cxf.rs.security.oauth2.provider; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration; import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.common.OAuthPermission; @@ -32,141 +28,55 @@ import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; import org.apache.cxf.rs.security.oauth2.common.UserSubject; import org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken; import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken; -import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants; -import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; public abstract class AbstractOAuthDataProvider implements OAuthDataProvider { private long accessTokenLifetime = 3600L; - - private long refreshTokenLifetime; // refresh tokens are eternal by default - private boolean recycleRefreshTokens = true; - private Map permissionMap = new HashMap(); - private MessageContext messageContext; - + private long refreshTokenLifetime = 360000L; protected AbstractOAuthDataProvider() { } @Override - public ServerAccessToken createAccessToken(AccessTokenRegistration reg) + public ServerAccessToken createAccessToken(AccessTokenRegistration accessToken) throws OAuthServiceException { - ServerAccessToken at = doCreateAccessToken(reg); - saveAccessToken(at); - if (isRefreshTokenSupported(reg.getApprovedScope())) { - createNewRefreshToken(at); - } - return at; - } - - protected ServerAccessToken doCreateAccessToken(AccessTokenRegistration accessToken) { - ServerAccessToken at = createNewAccessToken(accessToken.getClient()); - at.setAudience(accessToken.getAudience()); - at.setGrantType(accessToken.getGrantType()); - List theScopes = accessToken.getApprovedScope(); - List thePermissions = - convertScopeToPermissions(accessToken.getClient(), theScopes); - at.setScopes(thePermissions); - at.setSubject(accessToken.getSubject()); - at.setClientCodeVerifier(accessToken.getClientCodeVerifier()); - return at; - } - - @Override - public void removeAccessToken(ServerAccessToken token) throws OAuthServiceException { - revokeAccessToken(token.getTokenKey()); + ServerAccessToken serverToken = doCreateAccessToken(accessToken); + saveAccessToken(serverToken); + return serverToken; } @Override public ServerAccessToken refreshAccessToken(Client client, String refreshTokenKey, - List restrictedScopes) throws OAuthServiceException { - RefreshToken currentRefreshToken = recycleRefreshTokens - ? revokeRefreshToken(refreshTokenKey) : getRefreshToken(refreshTokenKey); - if (currentRefreshToken == null - || OAuthUtils.isExpired(currentRefreshToken.getIssuedAt(), currentRefreshToken.getExpiresIn())) { - throw new OAuthServiceException(OAuthConstants.ACCESS_DENIED); - } - if (recycleRefreshTokens) { - revokeAccessTokens(currentRefreshToken); - } - - ServerAccessToken at = doRefreshAccessToken(client, currentRefreshToken, restrictedScopes); - saveAccessToken(at); - if (recycleRefreshTokens) { - createNewRefreshToken(at); - } else { - updateRefreshToken(currentRefreshToken, at); - } - return at; + List requestedScopes) throws OAuthServiceException { + RefreshToken oldRefreshToken = revokeRefreshToken(client, refreshTokenKey); + + ServerAccessToken serverToken = doRefreshAccessToken(client, oldRefreshToken, requestedScopes); + saveAccessToken(serverToken); + return serverToken; } @Override public void revokeToken(Client client, String tokenKey, String tokenTypeHint) throws OAuthServiceException { - ServerAccessToken accessToken = null; - if (!OAuthConstants.REFRESH_TOKEN.equals(tokenTypeHint)) { - accessToken = revokeAccessToken(tokenKey); - } - if (accessToken != null) { - handleLinkedRefreshToken(accessToken); - } else if (!OAuthConstants.ACCESS_TOKEN.equals(tokenTypeHint)) { - RefreshToken currentRefreshToken = revokeRefreshToken(tokenKey); - revokeAccessTokens(currentRefreshToken); + if (revokeAccessToken(tokenKey)) { + return; } - } - protected void handleLinkedRefreshToken(ServerAccessToken accessToken) { - if (accessToken != null && accessToken.getRefreshToken() != null) { - RefreshToken rt = getRefreshToken(accessToken.getRefreshToken()); - if (rt == null) { - return; - } - - unlinkRefreshAccessToken(rt, accessToken.getTokenKey()); - if (rt.getAccessTokens().isEmpty()) { - revokeRefreshToken(rt.getTokenKey()); - } else { - saveRefreshToken(null, rt); - } - } - - } - protected void revokeAccessTokens(RefreshToken currentRefreshToken) { - if (currentRefreshToken != null) { - for (String accessTokenKey : currentRefreshToken.getAccessTokens()) { + RefreshToken oldRefreshToken = revokeRefreshToken(client, tokenKey); + if (oldRefreshToken != null) { + for (String accessTokenKey : oldRefreshToken.getAccessTokens()) { revokeAccessToken(accessTokenKey); } } } - - protected void unlinkRefreshAccessToken(RefreshToken rt, String tokenKey) { - List accessTokenKeys = rt.getAccessTokens(); - for (int i = 0; i < accessTokenKeys.size(); i++) { - if (accessTokenKeys.get(i).equals(tokenKey)) { - accessTokenKeys.remove(i); - break; - } - } - } - - @Override - public List convertScopeToPermissions(Client client, List requestedScopes) { - if (requestedScopes.isEmpty()) { + public List convertScopeToPermissions(Client client, + List requestedScope) { + if (requestedScope.isEmpty()) { return Collections.emptyList(); - } else if (!permissionMap.isEmpty()) { - List list = new ArrayList(); - for (String scope : requestedScopes) { - OAuthPermission permission = permissionMap.get(scope); - if (permission == null) { - throw new OAuthServiceException("Unexpected scope: " + scope); - } - list.add(permission); - } - return list; } else { - throw new OAuthServiceException("Requested scopes can not be mapped"); + throw new OAuthServiceException("Requested scopes can not be mapped to the permissions"); } } - + @Override public ServerAccessToken getPreauthorizedToken(Client client, List requestedScopes, UserSubject subject, String grantType) @@ -174,57 +84,52 @@ public abstract class AbstractOAuthDataProvider implements OAuthDataProvider { return null; } - protected boolean isRefreshTokenSupported(List theScopes) { - return true; + protected ServerAccessToken doCreateAccessToken(AccessTokenRegistration accessToken) { + ServerAccessToken at = createNewAccessToken(accessToken.getClient()); + at.setAudience(accessToken.getAudience()); + at.setGrantType(accessToken.getGrantType()); + List theScopes = accessToken.getApprovedScope(); + if (theScopes.isEmpty()) { + theScopes = accessToken.getRequestedScope(); + } + List thePermissions = + convertScopeToPermissions(accessToken.getClient(), theScopes); + at.setScopes(thePermissions); + at.setSubject(accessToken.getSubject()); + createNewRefreshToken(at); + return at; } - + protected ServerAccessToken createNewAccessToken(Client client) { return new BearerAccessToken(client, accessTokenLifetime); } - protected RefreshToken updateRefreshToken(RefreshToken rt, ServerAccessToken at) { - linkRefreshAccessTokens(rt, at); - saveRefreshToken(at, rt); - return rt; - } protected RefreshToken createNewRefreshToken(ServerAccessToken at) { - RefreshToken rt = doCreateNewRefreshToken(at); - saveRefreshToken(at, rt); - return rt; - } - protected RefreshToken doCreateNewRefreshToken(ServerAccessToken at) { RefreshToken rt = new RefreshToken(at.getClient(), refreshTokenLifetime); rt.setAudience(at.getAudience()); rt.setGrantType(at.getGrantType()); rt.setScopes(at.getScopes()); - rt.setSubject(at.getSubject()); - rt.setClientCodeVerifier(at.getClientCodeVerifier()); - linkRefreshAccessTokens(rt, at); - return rt; - } - - private void linkRefreshAccessTokens(RefreshToken rt, ServerAccessToken at) { rt.getAccessTokens().add(at.getTokenKey()); at.setRefreshToken(rt.getTokenKey()); + saveRefreshToken(at, rt); + return rt; } - + protected ServerAccessToken doRefreshAccessToken(Client client, RefreshToken oldRefreshToken, - List restrictedScopes) { + List requestedScopes) { ServerAccessToken at = createNewAccessToken(client); at.setAudience(oldRefreshToken.getAudience()); at.setGrantType(oldRefreshToken.getGrantType()); - at.setSubject(oldRefreshToken.getSubject()); - if (restrictedScopes.isEmpty()) { + List theNewScopes = convertScopeToPermissions(client, requestedScopes); + if (theNewScopes.isEmpty()) { at.setScopes(oldRefreshToken.getScopes()); + } else if (oldRefreshToken.getScopes().containsAll(theNewScopes)) { + at.setScopes(theNewScopes); } else { - List theNewScopes = convertScopeToPermissions(client, restrictedScopes); - if (oldRefreshToken.getScopes().containsAll(theNewScopes)) { - at.setScopes(theNewScopes); - } else { - throw new OAuthServiceException("Invalid scopes"); - } + throw new OAuthServiceException("Invalid scopes"); } + createNewRefreshToken(at); return at; } @@ -236,54 +141,9 @@ public abstract class AbstractOAuthDataProvider implements OAuthDataProvider { this.refreshTokenLifetime = refreshTokenLifetime; } - public void setRecycleRefreshTokens(boolean recycleRefreshTokens) { - this.recycleRefreshTokens = recycleRefreshTokens; - } - - public void init() { - } - - public void close() { - } - - public Map getPermissionMap() { - return permissionMap; - } - - public void setPermissionMap(Map permissionMap) { - this.permissionMap = permissionMap; - } - - public void setScopes(Map scopes) { - for (Map.Entry entry : scopes.entrySet()) { - OAuthPermission permission = new OAuthPermission(entry.getKey(), entry.getValue()); - permissionMap.put(entry.getKey(), permission); - } - } - - public MessageContext getMessageContext() { - return messageContext; - } - - public void setMessageContext(MessageContext messageContext) { - this.messageContext = messageContext; - } - - protected void removeClientTokens(Client c) { - for (RefreshToken rt : getRefreshTokens(c)) { - revokeRefreshToken(rt.getTokenKey()); - } - for (ServerAccessToken at : getAccessTokens(c)) { - revokeAccessToken(at.getTokenKey()); - } - } - protected abstract void saveAccessToken(ServerAccessToken serverToken); protected abstract void saveRefreshToken(ServerAccessToken at, RefreshToken refreshToken); - protected abstract ServerAccessToken revokeAccessToken(String accessTokenKey); - protected abstract List getAccessTokens(Client c); - protected abstract List getRefreshTokens(Client c); - protected abstract RefreshToken revokeRefreshToken(String refreshTokenKey); - protected abstract RefreshToken getRefreshToken(String refreshTokenKey); - + protected abstract boolean revokeAccessToken(String accessTokenKey); + protected abstract RefreshToken revokeRefreshToken(Client client, String refreshTokenKey); + } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEHCacheOAuthDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEHCacheOAuthDataProvider.java index 1611054..23891d2 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEHCacheOAuthDataProvider.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEHCacheOAuthDataProvider.java @@ -84,7 +84,6 @@ public class DefaultEHCacheOAuthDataProvider extends AbstractOAuthDataProvider public Client removeClient(String clientId) { Client c = getClient(clientId); clientCache.remove(clientId); - removeClientTokens(c); return c; } @@ -97,52 +96,23 @@ public class DefaultEHCacheOAuthDataProvider extends AbstractOAuthDataProvider } return clients; } - - @Override - protected List getAccessTokens(Client c) { - List keys = CastUtils.cast(accessTokenCache.getKeys()); - List tokens = new ArrayList(keys.size()); - for (String key : keys) { - ServerAccessToken token = getAccessToken(key); - if (token.getClient().getClientId().equals(c.getClientId())) { - tokens.add(token); - } - } - return tokens; - } - - @Override - protected List getRefreshTokens(Client c) { - List keys = CastUtils.cast(refreshTokenCache.getKeys()); - List tokens = new ArrayList(keys.size()); - for (String key : keys) { - RefreshToken token = getRefreshToken(key); - if (token.getClient().getClientId().equals(c.getClientId())) { - tokens.add(token); - } - } - return tokens; - } @Override public ServerAccessToken getAccessToken(String accessToken) throws OAuthServiceException { return getCacheValue(accessTokenCache, accessToken, ServerAccessToken.class); } + @Override - protected ServerAccessToken revokeAccessToken(String accessTokenKey) { - ServerAccessToken at = getAccessToken(accessTokenKey); - if (at != null) { - accessTokenCache.remove(accessTokenKey); - } - return at; + public void removeAccessToken(ServerAccessToken accessToken) throws OAuthServiceException { + revokeAccessToken(accessToken.getTokenKey()); } - @Override - protected RefreshToken getRefreshToken(String refreshTokenKey) { - return getCacheValue(refreshTokenCache, refreshTokenKey, RefreshToken.class); + + protected boolean revokeAccessToken(String accessTokenKey) { + return accessTokenCache.remove(accessTokenKey); } - @Override - protected RefreshToken revokeRefreshToken(String refreshTokenKey) { - RefreshToken refreshToken = getRefreshToken(refreshTokenKey); + + protected RefreshToken revokeRefreshToken(Client client, String refreshTokenKey) { + RefreshToken refreshToken = getCacheValue(refreshTokenCache, refreshTokenKey, RefreshToken.class); if (refreshToken != null) { refreshTokenCache.remove(refreshTokenKey); } @@ -222,9 +192,6 @@ public class DefaultEHCacheOAuthDataProvider extends AbstractOAuthDataProvider accessTokenCache = createCache(cacheManager, accessTokenKey); refreshTokenCache = createCache(cacheManager, refreshTokenKey); } - @Override - public void close() { - cacheManager.shutdown(); - } + } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEncryptingOAuthDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEncryptingOAuthDataProvider.java index 9bfee64..f139632 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEncryptingOAuthDataProvider.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEncryptingOAuthDataProvider.java @@ -32,7 +32,6 @@ import org.apache.cxf.common.util.crypto.KeyProperties; import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken; -import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants; import org.apache.cxf.rs.security.oauth2.utils.crypto.ModelEncryptionSupport; public class DefaultEncryptingOAuthDataProvider extends AbstractOAuthDataProvider @@ -65,7 +64,6 @@ public class DefaultEncryptingOAuthDataProvider extends AbstractOAuthDataProvide public Client removeClient(String clientId) { Client client = getClient(clientId); clientsMap.remove(clientId); - removeClientTokens(client); return client; } @Override @@ -76,43 +74,25 @@ public class DefaultEncryptingOAuthDataProvider extends AbstractOAuthDataProvide } return clients; } - @Override - protected List getAccessTokens(Client c) { - List list = new ArrayList(tokens.size()); - for (String tokenKey : tokens) { - ServerAccessToken token = getAccessToken(tokenKey); - if (token.getClient().getClientId().equals(c.getClientId())) { - list.add(token); - } - } - return list; - } - @Override - protected List getRefreshTokens(Client c) { - List list = new ArrayList(refreshTokens.size()); - for (String tokenKey : tokens) { - RefreshToken token = getRefreshToken(tokenKey); - if (token.getClient().getClientId().equals(c.getClientId())) { - list.add(token); - } - } - return list; - } + @Override public ServerAccessToken getAccessToken(String accessToken) throws OAuthServiceException { return ModelEncryptionSupport.decryptAccessToken(this, accessToken, key); } @Override + public void removeAccessToken(ServerAccessToken accessToken) throws OAuthServiceException { + revokeAccessToken(accessToken.getTokenKey()); + } + + @Override protected void saveAccessToken(ServerAccessToken serverToken) { encryptAccessToken(serverToken); } @Override - protected ServerAccessToken revokeAccessToken(String accessTokenKey) { - ServerAccessToken at = getAccessToken(accessTokenKey); - tokens.remove(accessTokenKey); - return at; + protected boolean revokeAccessToken(String accessTokenKey) { + return tokens.remove(accessTokenKey); } @Override @@ -122,14 +102,9 @@ public class DefaultEncryptingOAuthDataProvider extends AbstractOAuthDataProvide } @Override - protected RefreshToken revokeRefreshToken(String refreshTokenKey) { - RefreshToken rt = null; - if (refreshTokens.containsKey(refreshTokenKey)) { - rt = getRefreshToken(refreshTokenKey); - refreshTokens.remove(refreshTokenKey); - } - return rt; - + protected RefreshToken revokeRefreshToken(Client client, String refreshTokenKey) { + refreshTokens.remove(refreshTokenKey); + return ModelEncryptionSupport.decryptRefreshToken(this, refreshTokenKey, key); } private void encryptAccessToken(ServerAccessToken token) { @@ -138,13 +113,4 @@ public class DefaultEncryptingOAuthDataProvider extends AbstractOAuthDataProvide refreshTokens.put(token.getRefreshToken(), encryptedToken); token.setTokenKey(encryptedToken); } - @Override - protected RefreshToken getRefreshToken(String refreshTokenKey) { - try { - return ModelEncryptionSupport.decryptRefreshToken(this, refreshTokenKey, key); - } catch (SecurityException ex) { - throw new OAuthServiceException(OAuthConstants.ACCESS_DENIED, ex); - } - } - } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java index 21323c8..23d8053 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AbstractTokenService.java @@ -205,10 +205,6 @@ public class AbstractTokenService extends AbstractOAuthService { return createErrorResponseFromBean(new OAuthError(error)); } - protected Response createErrorResponseFromErrorCode(String error) { - return createErrorResponseFromBean(new OAuthError(error)); - } - protected Response createErrorResponseFromBean(OAuthError errorBean) { return JAXRSUtils.toResponseBuilder(400).entity(errorBean).build(); } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenRevocationService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenRevocationService.java index 26be81f..092b9ec 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenRevocationService.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenRevocationService.java @@ -53,17 +53,10 @@ public class TokenRevocationService extends AbstractTokenService { return createErrorResponse(params, OAuthConstants.UNSUPPORTED_TOKEN_TYPE); } String tokenTypeHint = params.getFirst(OAuthConstants.REVOKED_TOKEN_TYPE_HINT); - if (tokenTypeHint != null - && !OAuthConstants.ACCESS_TOKEN.equals(tokenTypeHint) - && !OAuthConstants.REFRESH_TOKEN.equals(tokenTypeHint)) { - return createErrorResponseFromErrorCode(OAuthConstants.UNSUPPORTED_TOKEN_TYPE); - } try { getDataProvider().revokeToken(client, token, tokenTypeHint); } catch (OAuthServiceException ex) { - // Spec: The authorization server responds with HTTP status code 200 if the - // token has been revoked successfully or if the client submitted an - // invalid token + return handleException(ex, OAuthConstants.UNSUPPORTED_TOKEN_TYPE); } return Response.ok().build(); } diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/ModelEncryptionSupport.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/ModelEncryptionSupport.java index 6e155bc..4e8face 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/ModelEncryptionSupport.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/ModelEncryptionSupport.java @@ -252,10 +252,8 @@ public final class ModelEncryptionSupport { } newToken.setScopes(perms); } - //Client verifier: - newToken.setClientCodeVerifier(parts[10]); //UserSubject: - newToken.setSubject(recreateUserSubject(parts[11])); + newToken.setSubject(recreateUserSubject(parts[10])); return newToken; } @@ -317,10 +315,7 @@ public final class ModelEncryptionSupport { } } state.append(SEP); - // 10: code verifier - state.append(tokenizeString(token.getClientCodeVerifier())); - state.append(SEP); - // 11: user subject + // 10: user subject tokenizeUserSubject(state, token.getSubject()); return state.toString(); @@ -424,7 +419,7 @@ public final class ModelEncryptionSupport { // 5: audience state.append(tokenizeString(grant.getAudience())); state.append(SEP); - // 6: code challenge + // 6: code verifier state.append(tokenizeString(grant.getClientCodeChallenge())); state.append(SEP); // 7: approved scopes