cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r931228 - in /cxf/trunk/rt: core/src/main/java/org/apache/cxf/interceptor/security/ ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/ ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/
Date Tue, 06 Apr 2010 17:07:15 GMT
Author: sergeyb
Date: Tue Apr  6 17:07:15 2010
New Revision: 931228

URL: http://svn.apache.org/viewvc?rev=931228&view=rev
Log:
CXF-2754,CXF-2755 : extending WSS4JInInterceptor, adding utility Authorizing interceptors

Added:
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
  (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AccessDeniedException.java
  (with props)
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
  (with props)
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
  (with props)
    cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
  (with props)
    cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/UserNameTokenAuthorizationTest.java
  (with props)
Modified:
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java?rev=931228&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
(added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
Tue Apr  6 17:07:15 2010
@@ -0,0 +1,69 @@
+/**
+ * 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.interceptor.security;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.cxf.frontend.MethodDispatcher;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.security.SecurityContext;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.BindingOperationInfo;
+
+public abstract class AbstractAuthorizingInInterceptor extends AbstractPhaseInterceptor<Message>
{
+
+    public AbstractAuthorizingInInterceptor() {
+        super(Phase.PRE_INVOKE);
+    }
+    
+    public void handleMessage(Message message) throws Fault {
+        SecurityContext sc = message.get(SecurityContext.class);
+        if (sc == null) {
+            return;
+        }
+        
+        Method method = getTargetMethod(message);
+        
+        List<String> expectedRoles = getExpectedRoles(method);
+        if (expectedRoles == null || expectedRoles.isEmpty()) {
+            return;
+        }
+        
+        for (String role : expectedRoles) {
+            if (sc.isUserInRole(role)) {
+                return;
+            }
+        }
+        
+        throw new AccessDeniedException("Unauthorized");
+    }
+    
+    private Method getTargetMethod(Message m) {
+        BindingOperationInfo bop = m.getExchange().get(BindingOperationInfo.class);
+        MethodDispatcher md = (MethodDispatcher) 
+            m.getExchange().get(Service.class).get(MethodDispatcher.class.getName());
+        return md.getMethod(bop);
+    }
+
+    protected abstract List<String> getExpectedRoles(Method method);
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AccessDeniedException.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AccessDeniedException.java?rev=931228&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AccessDeniedException.java
(added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AccessDeniedException.java
Tue Apr  6 17:07:15 2010
@@ -0,0 +1,25 @@
+/**
+ * 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.interceptor.security;
+
+public class AccessDeniedException extends RuntimeException {
+    public AccessDeniedException(String reason) {
+        super(reason);
+    }
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AccessDeniedException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AccessDeniedException.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java?rev=931228&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
(added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
Tue Apr  6 17:07:15 2010
@@ -0,0 +1,55 @@
+/**
+ * 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.interceptor.security;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+
+
+public class SimpleAuthorizingInterceptor extends AbstractAuthorizingInInterceptor {
+
+    private Map<String, List<String>> methodRolesMap;
+    private Map<String, List<String>> classRolesMap;
+    
+    
+    @Override
+    protected List<String> getExpectedRoles(Method method) {
+        List<String> roles = methodRolesMap.get(method.getName());
+        if (roles != null || classRolesMap == null) {
+            return roles;
+        }
+        return methodRolesMap.get(method.getDeclaringClass().getName());
+    }
+
+
+
+    public void setMethodRolesMap(Map<String, List<String>> rolesMap) {
+        this.methodRolesMap = rolesMap;
+    }
+    
+    public void setClassRolesMap(Map<String, List<String>> rolesMap) {
+        this.classRolesMap = rolesMap;
+    }
+
+
+
+    
+
+}

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java?rev=931228&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
(added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
Tue Apr  6 17:07:15 2010
@@ -0,0 +1,336 @@
+/**
+ * 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.ws.security.wss4j;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.security.SecurityContext;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSUsernameTokenPrincipal;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.processor.Processor;
+
+
+/**
+ * Base class providing an extensibility point for populating 
+ * javax.security.auth.Subject from a current UsernameToken.
+ * 
+ * WSS4J requires a password for validating digests which may not be available
+ * when external security systems provide for the authentication. This class
+ * implements WSS4J Processor interface so that it can delegate a UsernameToken
+ * validation to an external system.
+ * 
+ * In order to handle digests, this class currently creates a new WSS4J Security Engine for
+ * every request. If clear text passwords are expected then a supportDigestPasswords boolean
+ * property with a false value can be used to disable creating security engines.
+ * 
+ * Note that if a UsernameToken containing a clear text password has been encrypted then
+ * an application is expected to provide a password callback handler for decrypting the token
only.     
+ *
+ */
+public abstract class AbstractWSS4JSecurityContextProvidingInterceptor extends WSS4JInInterceptor

+    implements Processor {
+    
+    private static final Logger LOG = 
+        LogUtils.getL7dLogger(AbstractWSS4JSecurityContextProvidingInterceptor.class);
+    
+    private ThreadLocal<Message> messages = new ThreadLocal<Message>();
+    private boolean supportDigestPasswords;
+    
+    public void setSupportDigestPasswords(boolean support) {
+        supportDigestPasswords = support;
+    }
+    
+    @Override
+    public void handleFault(SoapMessage m) {
+        messages.remove();
+        super.handleFault(m);
+    }
+    
+    @Override
+    protected SecurityContext createSecurityContext(final Principal p) {
+        Message msg = messages.get();
+        if (msg == null) {
+            throw new IllegalStateException("Current message is not available");
+        }
+        messages.remove();
+        final Subject subject = msg.get(Subject.class);
+        return new SecurityContext() {
+            public Principal getUserPrincipal() {
+                return p;
+            }
+            public boolean isUserInRole(String role) {
+                if (subject == null || subject.getPrincipals().size() <= 1) {
+                    return false;
+                }
+                for (Principal p : subject.getPrincipals()) {
+                    if (p instanceof Group && ((Group)p).getName().equals(role))
{ 
+                        return true;
+                    }
+                }
+                return false;
+            }
+        };     
+    }
+
+    protected void setSubject(String name, 
+                              String password, 
+                              boolean isDigest,
+                              String nonce,
+                              String created) throws WSSecurityException {
+        Message msg = messages.get();
+        if (msg == null) {
+            throw new IllegalStateException("Current message is not available");
+        }
+        Subject subject = createSubject(name, password, isDigest, nonce, created);
+        if (subject == null || subject.getPrincipals().size() == 0
+            || !subject.getPrincipals().iterator().next().getName().equals(name)) {
+            throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION, null,
null);
+        }
+        msg.put(Subject.class, subject);
+    }
+    
+    /**
+     * Create a Subject representing a current user and its roles. 
+     * This Subject is expected to contain at least one Principal representing a user
+     * and optionally followed by one or more principal Groups this user is a member of.
 
+     * @param name username
+     * @param password password
+     * @param isDigest true if a password digest is used
+     * @param nonce optional nonce
+     * @param created optional timestamp
+     * @return subject
+     * @throws WSSecurityException
+     */
+    protected abstract Subject createSubject(String name, 
+                                    String password, 
+                                    boolean isDigest,
+                                    String nonce,
+                                    String created) throws WSSecurityException;
+    
+    
+    /**
+     * {@inheritDoc}
+     * 
+     */
+    @Override
+    protected CallbackHandler getCallback(RequestData reqData, int doAction) 
+        throws WSSecurityException {
+        
+        if ((doAction & WSConstants.UT) != 0) {
+            messages.set((Message)reqData.getMsgContext());
+            if (!supportDigestPasswords) {    
+                CallbackHandler pwdCallback = null;
+                try {
+                    pwdCallback = super.getCallback(reqData, doAction);
+                } catch (Exception ex) {
+                    // ignore
+                }
+                return new DelegatingCallbackHandler(pwdCallback);
+            }
+        }
+        
+        
+        return super.getCallback(reqData, doAction);
+    }
+    
+    @Override 
+    protected WSSecurityEngine getSecurityEngine() {
+        if (!supportDigestPasswords) {
+            return super.getSecurityEngine();
+        }
+        Map<QName, Object> profiles = new HashMap<QName, Object>(3);
+        profiles.put(new QName(WSConstants.USERNAMETOKEN_NS, WSConstants.USERNAME_TOKEN_LN),
this);
+        profiles.put(new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN), this);
+        profiles.put(new QName(WSConstants.WSSE11_NS, WSConstants.USERNAME_TOKEN_LN), this);
+        return createSecurityEngine(profiles);
+    }
+    
+    public void handleToken(Element elem, 
+                            Crypto crypto, 
+                            Crypto decCrypto, 
+                            CallbackHandler cb, 
+                            WSDocInfo wsDocInfo, 
+                            Vector returnResults, 
+                            WSSConfig config) throws WSSecurityException {
+        new CustomUsernameTokenProcessor().handleToken(elem, crypto, decCrypto, cb, wsDocInfo,

+                                                       returnResults, config);
+    }
+    
+    
+    private class DelegatingCallbackHandler implements CallbackHandler {
+
+        private CallbackHandler pwdHandler;
+        
+        public DelegatingCallbackHandler(CallbackHandler pwdHandler) {
+            this.pwdHandler = pwdHandler;
+        }
+        
+        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
+            for (Callback c : callbacks) {
+                if (c instanceof WSPasswordCallback) {
+                    WSPasswordCallback pc = (WSPasswordCallback)c;
+                    if (WSConstants.PASSWORD_TEXT.equals(pc.getPasswordType()) 
+                        && pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN)
{
+                        AbstractWSS4JSecurityContextProvidingInterceptor.this.setSubject(
+                            pc.getIdentifier(), pc.getPassword(), false, null, null);
+                    } else if (pwdHandler != null) {
+                        pwdHandler.handle(callbacks);
+                    }
+                }
+            }
+            
+        }
+        
+    }
+    
+    /**
+     * Custom UsernameTokenProcessor
+     * Unfortunately, WSS4J UsernameTokenProcessor makes it impossible to
+     * override its handleUsernameToken only. 
+     *
+     */
+    private class CustomUsernameTokenProcessor implements Processor {
+        
+        private String utId;
+        private UsernameToken ut;
+        
+        @SuppressWarnings("unchecked")
+        public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler
cb, 
+            WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException
{
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Found UsernameToken list element");
+            }
+            
+            Principal principal = handleUsernameToken((Element) elem, cb);
+            returnResults.add(
+                0, 
+                new WSSecurityEngineResult(WSConstants.UT, principal, null, null, null)
+            );
+            utId = ut.getID();
+        }
+        
+        private WSUsernameTokenPrincipal handleUsernameToken(
+            Element token, CallbackHandler cb) throws WSSecurityException {
+            //
+            // Parse the UsernameToken element
+            //
+            ut = new UsernameToken(token, false);
+            String user = ut.getName();
+            String password = ut.getPassword();
+            String nonce = ut.getNonce();
+            String createdTime = ut.getCreated();
+            String pwType = ut.getPasswordType();
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("UsernameToken user " + user);
+                LOG.fine("UsernameToken password " + password);
+            }
+            
+            AbstractWSS4JSecurityContextProvidingInterceptor.this.setSubject(
+                user, password, ut.isHashed(), nonce, createdTime);    
+            
+            WSUsernameTokenPrincipal principal = new WSUsernameTokenPrincipal(user, ut.isHashed());
+            principal.setNonce(nonce);
+            principal.setPassword(password);
+            principal.setCreatedTime(createdTime);
+            principal.setPasswordType(pwType);
+
+            return principal;
+        }
+
+        public String getId() {
+            return utId;
+        }
+    }
+    
+    /**
+     * Simple Principal implementation
+     *
+     */
+    protected static class SimplePrincipal implements Principal {
+
+        private String name;
+        
+        public SimplePrincipal(String name) {
+            this.name = name;
+        }
+        
+        public String getName() {
+            return name;
+        }
+        
+    }
+    
+    /**
+     * Simple Group implementation
+     *
+     */
+    protected static class SimpleGroup extends SimplePrincipal implements Group {
+        
+        private String memberName;
+        
+        public SimpleGroup(String roleName, String memberName) {
+            super(roleName);
+            this.memberName = memberName;
+        }
+
+        public boolean isMember(Principal p) {
+            return memberName.equals(p.getName());
+        }
+
+        public boolean addMember(Principal p) {
+            throw new UnsupportedOperationException();
+        }
+        
+        public Enumeration<? extends Principal> members() {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean removeMember(Principal arg0) {
+            throw new UnsupportedOperationException();
+        }
+    }
+}

Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java?rev=931228&r1=931227&r2=931228&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
(original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
Tue Apr  6 17:07:15 2010
@@ -396,21 +396,25 @@ public class WSS4JInInterceptor extends 
                 msg.put(PRINCIPAL_RESULT, p);                   
                 SecurityContext sc = msg.get(SecurityContext.class);
                 if (sc == null || sc.getUserPrincipal() == null) {
-                    SecurityContext c = new SecurityContext() {
-                        public Principal getUserPrincipal() {
-                            return p;
-                        }
-                        public boolean isUserInRole(String role) {
-                            return false;
-                        }
-                    };
-                    msg.put(SecurityContext.class, c);
+                    msg.put(SecurityContext.class, createSecurityContext(p));
                     break;
                 }
             }            
         }
     }
 
+    
+    protected SecurityContext createSecurityContext(final Principal p) {
+        return new SecurityContext() {
+            public Principal getUserPrincipal() {
+                return p;
+            }
+            public boolean isUserInRole(String role) {
+                return false;
+            }
+        };
+    }
+    
     private String getAction(SoapMessage msg, SoapVersion version) {
         String action = (String)getOption(WSHandlerConstants.ACTION);
         if (action == null) {
@@ -461,7 +465,7 @@ public class WSS4JInInterceptor extends 
         
     }
 
-    private CallbackHandler getCallback(RequestData reqData, int doAction) throws WSSecurityException
{
+    protected CallbackHandler getCallback(RequestData reqData, int doAction) throws WSSecurityException
{
         /*
          * To check a UsernameToken or to decrypt an encrypted message we need a
          * password.
@@ -519,7 +523,7 @@ public class WSS4JInInterceptor extends 
      * TODO the WSHandler base class defines secEngine to be static, which
      * is really bad, because the engine has mutable state on it.
      */
-    private WSSecurityEngine
+    protected WSSecurityEngine
     getSecurityEngine() {
         if (secEngineOverride != null) {
             return secEngineOverride;
@@ -535,7 +539,7 @@ public class WSS4JInInterceptor extends 
      * TODO The WSS4J APIs leave something to be desired here, but hopefully
      * we'll clean all this up in WSS4J-2.0
      */
-    private static WSSecurityEngine
+    protected static WSSecurityEngine
     createSecurityEngine(
         final Map<QName, Object> map
     ) {

Added: cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java?rev=931228&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
(added)
+++ cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
Tue Apr  6 17:07:15 2010
@@ -0,0 +1,43 @@
+/**
+ * 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.ws.security.wss4j;
+
+import javax.security.auth.Subject;
+
+import org.apache.ws.security.WSSecurityException;
+
+public class SimpleSubjectCreatingInterceptor extends AbstractWSS4JSecurityContextProvidingInterceptor
{
+
+    @Override
+    protected Subject createSubject(String name, 
+                                    String password, 
+                                    boolean isDigest,
+                                    String nonce,
+                                    String created) throws WSSecurityException {
+        Subject subject = new Subject();
+         
+        // delegate to the external security system if possible
+         
+        subject.getPrincipals().add(new SimplePrincipal(name));
+        subject.getPrincipals().add(new SimpleGroup("developers", name));
+        subject.setReadOnly();
+        return subject;
+    }
+
+}

Propchange: cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/UserNameTokenAuthorizationTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/UserNameTokenAuthorizationTest.java?rev=931228&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/UserNameTokenAuthorizationTest.java
(added)
+++ cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/UserNameTokenAuthorizationTest.java
Tue Apr  6 17:07:15 2010
@@ -0,0 +1,183 @@
+/**
+ * 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.ws.security.wss4j;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.ws.BindingProvider;
+
+import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
+import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.interceptor.LoggingInInterceptor;
+import org.apache.cxf.interceptor.LoggingOutInterceptor;
+import org.apache.cxf.interceptor.security.SimpleAuthorizingInterceptor;
+import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
+import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.transport.local.LocalConduit;
+import org.apache.cxf.transport.local.LocalTransportFactory;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.handler.WSHandlerConstants;
+
+import org.junit.Test;
+
+public class UserNameTokenAuthorizationTest extends AbstractSecurityTest {
+    private SimpleSubjectCreatingInterceptor wsIn;
+    private WSS4JOutInterceptor wsOut;
+    private Echo echo;
+    private Client client;
+
+    public void setUpService(List<String> expectedRoles,
+                             boolean digest,
+                             boolean encryptUsernameTokenOnly) throws Exception {
+        JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
+        factory.setServiceBean(new EchoImpl());
+        factory.setAddress("local://Echo");
+        factory.setTransportId(LocalTransportFactory.TRANSPORT_ID);
+        Server server = factory.create();
+        Service service = server.getEndpoint().getService();
+        
+        service.getInInterceptors().add(new SAAJInInterceptor());
+        service.getInInterceptors().add(new LoggingInInterceptor());
+        service.getOutInterceptors().add(new SAAJOutInterceptor());
+        service.getOutInterceptors().add(new LoggingOutInterceptor());
+
+        wsIn = new SimpleSubjectCreatingInterceptor();
+        wsIn.setSupportDigestPasswords(digest);
+        wsIn.setProperty(WSHandlerConstants.SIG_PROP_FILE, "META-INF/cxf/insecurity.properties");
+        wsIn.setProperty(WSHandlerConstants.DEC_PROP_FILE, "META-INF/cxf/insecurity.properties");
+        wsIn.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, TestPwdCallback.class.getName());
+
+        service.getInInterceptors().add(wsIn);
+         
+        SimpleAuthorizingInterceptor sai = new SimpleAuthorizingInterceptor();
+        sai.setMethodRolesMap(Collections.singletonMap("echo", expectedRoles));
+        service.getInInterceptors().add(sai);
+        
+        
+        wsOut = new WSS4JOutInterceptor();
+        wsOut.setProperty(WSHandlerConstants.SIG_PROP_FILE, "META-INF/cxf/outsecurity.properties");
+        wsOut.setProperty(WSHandlerConstants.ENC_PROP_FILE, "META-INF/cxf/outsecurity.properties");
+        wsOut.setProperty(WSHandlerConstants.USER, "myalias");
+        if (digest) {
+            wsOut.setProperty("password", "myAliasPassword");
+        } else {
+            wsOut.setProperty(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
+        }
+        
+        if (encryptUsernameTokenOnly) {
+            wsOut.setProperty(WSHandlerConstants.ENCRYPTION_USER, "myalias");
+            wsOut.setProperty(
+                WSHandlerConstants.ENCRYPTION_PARTS, 
+                "{Content}{" + WSConstants.WSSE_NS + "}UsernameToken"
+            );
+        }
+        wsOut.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, TestPwdCallback.class.getName());
+        service.getOutInterceptors().add(wsOut);
+
+        // Create the client
+        JaxWsProxyFactoryBean proxyFac = new JaxWsProxyFactoryBean();
+        proxyFac.setServiceClass(Echo.class);
+        proxyFac.setAddress("local://Echo");
+        proxyFac.getClientFactoryBean().setTransportId(LocalTransportFactory.TRANSPORT_ID);
+        
+        echo = (Echo)proxyFac.create();
+
+        ((BindingProvider)echo).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);
+
+        
+        client = ClientProxy.getClient(echo);
+        
+        client.getInInterceptors().add(new LoggingInInterceptor());
+        client.getInInterceptors().add(wsIn);
+        client.getInInterceptors().add(new SAAJInInterceptor());
+        client.getOutInterceptors().add(new LoggingOutInterceptor());
+        client.getOutInterceptors().add(wsOut);
+        client.getOutInterceptors().add(new SAAJOutInterceptor());
+    }
+
+    
+    @Test
+    public void testDigestPasswordAuthorized() throws Exception {
+        setUpService(Collections.singletonList("developers"), true, false);
+        String actions = WSHandlerConstants.ENCRYPT + " " + WSHandlerConstants.SIGNATURE
+ " "
+                         + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.USERNAME_TOKEN;
+
+        wsIn.setProperty(WSHandlerConstants.ACTION, actions);
+        
+        wsOut.setProperty(WSHandlerConstants.ACTION, actions);
+
+        assertEquals("test", echo.echo("test"));
+    }
+    
+    @Test
+    public void testDigestPasswordUnauthorized() throws Exception {
+        setUpService(Collections.singletonList("managers"), true, false);
+        String actions = WSHandlerConstants.ENCRYPT + " " + WSHandlerConstants.SIGNATURE
+ " "
+                         + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.USERNAME_TOKEN;
+
+        wsIn.setProperty(WSHandlerConstants.ACTION, actions);
+        
+        wsOut.setProperty(WSHandlerConstants.ACTION, actions);
+
+        try {
+            echo.echo("test");
+            fail("Exception expected");
+        } catch (Exception ex) {
+            assertEquals("Unauthorized", ex.getMessage());
+        }
+    }
+    
+    @Test
+    public void testEncryptedDigestPasswordAuthorized() throws Exception {
+        setUpService(Collections.singletonList("developers"), true, true);
+        String actions = WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.ENCRYPT;
+
+        wsIn.setProperty(WSHandlerConstants.ACTION, actions);
+        wsOut.setProperty(WSHandlerConstants.ACTION, actions);
+
+        assertEquals("test", echo.echo("test"));
+    }
+    
+    @Test
+    public void testClearPasswordAuthorized() throws Exception {
+        setUpService(Collections.singletonList("developers"), false, false);
+        String actions = WSHandlerConstants.USERNAME_TOKEN;
+
+        wsIn.setProperty(WSHandlerConstants.ACTION, actions);
+        wsOut.setProperty(WSHandlerConstants.ACTION, actions);
+
+        assertEquals("test", echo.echo("test"));
+    }
+    
+    @Test
+    public void testEncyptedClearPasswordAuthorized() throws Exception {
+        setUpService(Collections.singletonList("developers"), false, true);
+        String actions = WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.ENCRYPT;
+
+        wsIn.setProperty(WSHandlerConstants.ACTION, actions);
+        wsOut.setProperty(WSHandlerConstants.ACTION, actions);
+
+        assertEquals("test", echo.echo("test"));
+    }
+}

Propchange: cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/UserNameTokenAuthorizationTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/UserNameTokenAuthorizationTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



Mime
View raw message