diff --git a/config/alfresco/cmis-ws-context.xml b/config/alfresco/cmis-ws-context.xml index bedeb70be2..3be4072184 100644 --- a/config/alfresco/cmis-ws-context.xml +++ b/config/alfresco/cmis-ws-context.xml @@ -18,11 +18,13 @@ + + @@ -45,11 +47,13 @@ + + @@ -71,11 +75,13 @@ + + @@ -99,11 +105,13 @@ + + @@ -126,11 +134,13 @@ + + @@ -153,11 +163,13 @@ + + @@ -180,11 +192,13 @@ + + @@ -206,11 +220,13 @@ + + @@ -352,6 +368,11 @@ - + + + + + + \ No newline at end of file diff --git a/source/java/org/alfresco/repo/cmis/ws/AuthenticationClearInterceptor.java b/source/java/org/alfresco/repo/cmis/ws/AuthenticationClearInterceptor.java new file mode 100644 index 0000000000..cc54d2939e --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/ws/AuthenticationClearInterceptor.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2005-2008 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.cmis.ws; + +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.apache.cxf.binding.soap.SoapMessage; +import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.phase.Phase; + +/** + * @author Dmitry Velichkevich + */ +public class AuthenticationClearInterceptor extends AbstractSoapInterceptor +{ + public AuthenticationClearInterceptor() + { + super(Phase.PRE_INVOKE); + } + + public void handleMessage(SoapMessage message) throws Fault + { + AuthenticationUtil.clearCurrentSecurityContext(); + } + + @Override + public void handleFault(SoapMessage message) + { + AuthenticationUtil.clearCurrentSecurityContext(); + super.handleFault(message); + } +} diff --git a/source/java/org/alfresco/repo/cmis/ws/AuthenticationInterceptor.java b/source/java/org/alfresco/repo/cmis/ws/AuthenticationInterceptor.java index 90e5060574..48f3eb840b 100644 --- a/source/java/org/alfresco/repo/cmis/ws/AuthenticationInterceptor.java +++ b/source/java/org/alfresco/repo/cmis/ws/AuthenticationInterceptor.java @@ -26,7 +26,9 @@ package org.alfresco.repo.cmis.ws; import java.util.List; -import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.transaction.TransactionService; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; import org.apache.cxf.interceptor.Fault; @@ -36,8 +38,13 @@ import org.apache.ws.security.WSUsernameTokenPrincipal; import org.apache.ws.security.handler.WSHandlerConstants; import org.apache.ws.security.handler.WSHandlerResult; +/** + * @author Dmitry Velichkevich + */ public class AuthenticationInterceptor extends AbstractSoapInterceptor { + private AuthenticationService authenticationService; + private TransactionService transactionService; public AuthenticationInterceptor() { @@ -49,10 +56,34 @@ public class AuthenticationInterceptor extends AbstractSoapInterceptor @SuppressWarnings("unchecked") WSHandlerResult handlerResult = ((List) message.getContextualProperty(WSHandlerConstants.RECV_RESULTS)).get(0); WSSecurityEngineResult secRes = (WSSecurityEngineResult) handlerResult.getResults().get(0); - WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes.get(WSSecurityEngineResult.TAG_PRINCIPAL); + final WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes.get(WSSecurityEngineResult.TAG_PRINCIPAL); // Authenticate - AuthenticationUtil.setFullyAuthenticatedUser(principal.getName()); + transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + public Object execute() throws Throwable + { + try + { + authenticationService.authenticate(principal.getName(), principal.getPassword().toCharArray()); + } + catch (Throwable e) + { + throw new SecurityException("Invalid user name or password specified"); + } + + return null; + } + }); } + public void setAuthenticationService(AuthenticationService authenticationService) + { + this.authenticationService = authenticationService; + } + + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } } diff --git a/source/java/org/alfresco/repo/cmis/ws/AuthenticationTokenCallbackHandler.java b/source/java/org/alfresco/repo/cmis/ws/AuthenticationTokenCallbackHandler.java index 1006b76532..22cf1fed61 100644 --- a/source/java/org/alfresco/repo/cmis/ws/AuthenticationTokenCallbackHandler.java +++ b/source/java/org/alfresco/repo/cmis/ws/AuthenticationTokenCallbackHandler.java @@ -30,41 +30,26 @@ import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; +import org.apache.ws.security.WSConstants; import org.apache.ws.security.WSPasswordCallback; /** - * @author Michael Shavnev + * @author Dmitry Velichkevich */ public class AuthenticationTokenCallbackHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback wssPasswordCallback = (WSPasswordCallback) callbacks[0]; - String userName = wssPasswordCallback.getIdentifer(); - String password = getPassword(userName); - // Check the UsernameToken element. - // Depending on the password type contained in the element the processing differs. - if (wssPasswordCallback.getUsage() == WSPasswordCallback.USERNAME_TOKEN) + if ((WSPasswordCallback.USERNAME_TOKEN_UNKNOWN != wssPasswordCallback.getUsage()) && (WSPasswordCallback.USERNAME_TOKEN != wssPasswordCallback.getUsage())) { - // If the password type is password digest provide stored password perform - // hash algorithm and compare the result with the transmitted password - wssPasswordCallback.setPassword(password); + throw new SecurityException("Only 'UsernameToken' usage is supported."); } - else + + if (!WSConstants.PASSWORD_TEXT.equals(wssPasswordCallback.getPasswordType())) { - // If the password is of type password text or any other yet unknown password type - // the delegate the password validation to the callback class. - if (!password.equals(wssPasswordCallback.getPassword())) - { - throw new SecurityException("Incorrect password"); - } + throw new SecurityException("Password type '" + wssPasswordCallback.getPasswordType() + "' unsupported. Only '" + WSConstants.PW_TEXT + "' is supported."); } } - - private String getPassword(String userName) - { - return userName; - } - } diff --git a/source/test/java/org/alfresco/repo/cmis/ws/CmisServiceTestHelper.java b/source/test/java/org/alfresco/repo/cmis/ws/CmisServiceTestHelper.java index df1710e3b3..35ff4c49a1 100755 --- a/source/test/java/org/alfresco/repo/cmis/ws/CmisServiceTestHelper.java +++ b/source/test/java/org/alfresco/repo/cmis/ws/CmisServiceTestHelper.java @@ -169,7 +169,7 @@ public class CmisServiceTestHelper extends TestCase wss4jOutInterceptorProp.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP); wss4jOutInterceptorProp.put(WSHandlerConstants.USER, username); - wss4jOutInterceptorProp.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST); + wss4jOutInterceptorProp.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT); wss4jOutInterceptorProp.put(WSHandlerConstants.PW_CALLBACK_REF, new CallbackHandler() {