Repository: cxf-fediz Updated Branches: refs/heads/master fac4db415 -> 3ba499aef
Introducing ProviderAuthenticationStrategy to make it easier to encapsulate alternative approaches for authenticating at the provider level Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/3ba499ae Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/3ba499ae Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/3ba499ae Branch: refs/heads/master Commit: 3ba499aeffb16c84895022e953a117f922abc4c4 Parents: fac4db4 Author: Sergey Beryozkin <sberyoz...@gmail.com> Authored: Thu Mar 2 22:03:34 2017 +0000 Committer: Sergey Beryozkin <sberyoz...@gmail.com> Committed: Thu Mar 2 22:03:34 2017 +0000 ---------------------------------------------------------------------- .../service/oidc/OAuthDataProviderImpl.java | 79 +++++++++----------- .../src/test/resources/oidc/data-manager.xml | 8 +- 2 files changed, 41 insertions(+), 46 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/3ba499ae/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/OAuthDataProviderImpl.java ---------------------------------------------------------------------- diff --git a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/OAuthDataProviderImpl.java b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/OAuthDataProviderImpl.java index 1882e0a..c265cef 100644 --- a/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/OAuthDataProviderImpl.java +++ b/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/OAuthDataProviderImpl.java @@ -18,19 +18,12 @@ */ package org.apache.cxf.fediz.service.oidc; +import java.lang.reflect.Method; import java.security.Principal; import java.util.Collections; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.login.Configuration; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; - -import org.apache.cxf.common.logging.LogUtils; -import org.apache.cxf.interceptor.security.NamePasswordCallbackHandler; +import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.common.OAuthPermission; import org.apache.cxf.rs.security.oauth2.grants.code.DefaultEHCacheCodeDataProvider; @@ -40,23 +33,18 @@ import org.apache.cxf.rs.security.oidc.utils.OidcUtils; public class OAuthDataProviderImpl extends DefaultEHCacheCodeDataProvider { - private static final Logger LOG = LogUtils.getL7dLogger(OAuthDataProviderImpl.class); - private boolean checkOnlyRegisteredClients; private boolean persistUnregisteredClients = true; - private String contextName; - private Configuration loginConfig; - - + private ProviderAuthenticationStrategy authenticationStrategy; + @Override public Client getClient(String clientId) { - //TODO: push most of this code into the abstract class Client client = super.getClient(clientId); if (client != null || checkOnlyRegisteredClients) { return client; } - String grantType = (String)getMessageContext().get(OAuthConstants.GRANT_TYPE); + String grantType = getCurrentRequestedGrantType(); if (OAuthConstants.CLIENT_CREDENTIALS_GRANT.equals(grantType)) { // Pre-registering the OAuth2 Client representations for // "client_credentials" can be difficult. @@ -81,47 +69,32 @@ public class OAuthDataProviderImpl extends DefaultEHCacheCodeDataProvider { // (as it is now) but also client credentials/etc then the check below will need to be more strict // with the help of getMessageContext().get(OAuthConstants.GRANT_TYPE) if (!client.getAllowedGrantTypes().contains(OAuthConstants.CLIENT_CREDENTIALS_GRANT) + && !client.getAllowedGrantTypes().contains(OAuthConstants.RESOURCE_OWNER_GRANT) && !requestedScopes.contains(OidcUtils.OPENID_SCOPE)) { throw new OAuthServiceException("Required scopes are missing"); } return super.convertScopeToPermissions(client, requestedScopes); } - protected Client authenticateClient(String clientId, String clientSecret) { - if (contextName != null) { - try { - // Login using JAAS - CallbackHandler callbackHandler = - new NamePasswordCallbackHandler(clientId, clientSecret); - LoginContext ctx = new LoginContext(contextName, null, callbackHandler, loginConfig); - ctx.login(); - Client client = createClientCredClient(clientId, clientSecret); - ctx.logout(); - return client; - } catch (LoginException ex) { - String errorMessage = "Authentication failed: " + ex.getMessage(); - LOG.log(Level.FINE, errorMessage, ex); - } - } - return null; - } - public void setCheckOnlyRegisteredClients(boolean checkOnlyRegisteredClients) { this.checkOnlyRegisteredClients = checkOnlyRegisteredClients; } - public void setContextName(String contextName) { - this.contextName = contextName; - } - - public void setLoginConfig(Configuration loginConfig) { - this.loginConfig = loginConfig; - } - public void setPersistUnregisteredClients(boolean persistUnregisteredClients) { this.persistUnregisteredClients = persistUnregisteredClients; } + public void setAuthenticationStrategy(ProviderAuthenticationStrategy authenticationStrategy) { + this.authenticationStrategy = authenticationStrategy; + } + + protected Client authenticateClient(String clientId, String clientSecret) { + if (doAuthenticate(clientId, clientSecret)) { + return createClientCredClient(clientId, clientSecret); + } + return null; + } + protected Client createClientCredClient(String clientId, String password) { Client c = new Client(clientId, password, true); c.setAllowedGrantTypes(Collections.singletonList(OAuthConstants.CLIENT_CREDENTIALS_GRANT)); @@ -131,4 +104,22 @@ public class OAuthDataProviderImpl extends DefaultEHCacheCodeDataProvider { } return c; } + + protected boolean doAuthenticate(String id, String password) { + return authenticationStrategy != null + && authenticationStrategy.authenticate(id, password); + } + @Override + public void setMessageContext(MessageContext mc) { + super.setMessageContext(mc); + if (authenticationStrategy != null) { + try { + Method contextMethod = authenticationStrategy.getClass().getMethod("setMessageContext", + new Class[]{MessageContext.class}); + contextMethod.invoke(authenticationStrategy, new Object[]{mc}); + } catch (Throwable t) { + // ignore + } + } + } } http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/3ba499ae/systests/oidc/src/test/resources/oidc/data-manager.xml ---------------------------------------------------------------------- diff --git a/systests/oidc/src/test/resources/oidc/data-manager.xml b/systests/oidc/src/test/resources/oidc/data-manager.xml index cd6593d..a5c2c56 100644 --- a/systests/oidc/src/test/resources/oidc/data-manager.xml +++ b/systests/oidc/src/test/resources/oidc/data-manager.xml @@ -54,7 +54,11 @@ <!-- To support the alternative data persistence strategies: either register a custom AbstractCodeDataProvider extension or implement AuthorizationCodeDataProvider directly - --> + --> + <bean id="authenticationStrategy" + class="org.apache.cxf.fediz.service.oidc.JAASAuthenticationStrategy"> + <property name="contextName" value="sts"/> + </bean> <bean id="oauthProvider" class="org.apache.cxf.fediz.service.oidc.OAuthDataProviderImpl" init-method="init" destroy-method="close"> @@ -75,7 +79,7 @@ <!-- <property name="supportPreauthorizedTokens" value="true"/> --> - <property name="contextName" value="sts"/> + <property name="authenticationStrategy" ref="authenticationStrategy"/> </bean> <!-- Custom SubjectCreator where IdToken is created -->