cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r933326 - in /cxf/trunk: common/common/src/main/java/org/apache/cxf/common/security/ common/common/src/test/java/org/apache/cxf/common/security/ rt/core/src/main/java/org/apache/cxf/interceptor/security/ rt/core/src/test/java/org/apache/cxf...
Date Mon, 12 Apr 2010 17:07:20 GMT
Author: sergeyb
Date: Mon Apr 12 17:07:19 2010
New Revision: 933326

URL: http://svn.apache.org/viewvc?rev=933326&view=rev
Log:
CXF-2754,CXF-2755: some refactoring, adding unit tests

Added:
    cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/
    cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimpleGroup.java
  (with props)
    cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimplePrincipal.java
  (with props)
    cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/
    cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimpleGroupTest.java
  (with props)
    cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimplePrincipalTest.java
  (with props)
    cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/
    cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
  (with props)
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContext.java
  (with props)
    cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContextTest.java
  (with props)
Modified:
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
    cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java

Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimpleGroup.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimpleGroup.java?rev=933326&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimpleGroup.java
(added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimpleGroup.java
Mon Apr 12 17:07:19 2010
@@ -0,0 +1,91 @@
+/**
+ * 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.common.security;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Simple Group implementation
+ *
+ */
+public class SimpleGroup extends SimplePrincipal implements Group {
+    
+    private Set<Principal> members = new HashSet<Principal>();
+    
+    public SimpleGroup(String groupName) {
+        super(groupName);
+    }
+    
+    public SimpleGroup(String groupName, String memberName) {
+        super(groupName);
+        members.add(new SimplePrincipal(memberName));
+    }
+    
+    public SimpleGroup(String groupName, Principal member) {
+        super(groupName);
+        members.add(member);
+    }
+
+    public boolean isMember(Principal p) {
+        return members.contains(p);
+    }
+
+    public boolean addMember(Principal p) {
+        return members.add(p);
+    }
+    
+    public Enumeration<? extends Principal> members() {
+        
+        final Iterator<Principal> it = members.iterator();
+        
+        return new Enumeration<Principal>() {
+
+            public boolean hasMoreElements() {
+                return it.hasNext();
+            }
+
+            public Principal nextElement() {
+                return it.next();
+            }
+            
+        };
+    }
+
+    public boolean removeMember(Principal p) {
+        return members.remove(p);
+    }
+    
+    public boolean equals(Object obj) {
+        if (!(obj instanceof SimpleGroup)) {
+            return false;
+        }
+        SimpleGroup other = (SimpleGroup)obj;
+        return getName().equals(other.getName()) && members.equals(other.members);
+    }
+    
+    public int hashCode() {
+        return getName().hashCode() + 37 * members.hashCode();
+    }
+}
+

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimpleGroup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimpleGroup.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimplePrincipal.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimplePrincipal.java?rev=933326&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimplePrincipal.java
(added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimplePrincipal.java
Mon Apr 12 17:07:19 2010
@@ -0,0 +1,57 @@
+/**
+ * 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.common.security;
+
+import java.security.Principal;
+
+/**
+ * Simple Principal implementation
+ *
+ */
+public class SimplePrincipal implements Principal {
+
+    private String name;
+    
+    public SimplePrincipal(String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("Principal name can not be null");
+        }
+        this.name = name;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public boolean equals(Object obj) {
+        if (!(obj instanceof SimplePrincipal)) {
+            return false;
+        }
+        
+        return name.equals(((SimplePrincipal)obj).name);
+    }
+    
+    public int hashCode() {
+        return name.hashCode();
+    }
+    
+    public String toString() {
+        return name;
+    }
+}

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimplePrincipal.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimplePrincipal.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimpleGroupTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimpleGroupTest.java?rev=933326&view=auto
==============================================================================
--- cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimpleGroupTest.java
(added)
+++ cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimpleGroupTest.java
Mon Apr 12 17:07:19 2010
@@ -0,0 +1,57 @@
+/**
+ * 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.common.security;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Enumeration;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SimpleGroupTest extends Assert {
+
+    @Test
+    public void testName() {
+        assertEquals("group", new SimpleGroup("group", "friend").getName());
+        assertEquals("group", new SimpleGroup("group", new SimplePrincipal("friend")).getName());
+    }
+    
+    @Test
+    public void testIsMember() {
+        assertTrue(new SimpleGroup("group", "friend").isMember(new SimplePrincipal("friend")));
+        assertFalse(new SimpleGroup("group", "friend").isMember(new SimplePrincipal("frogs")));
+    }
+        
+    @Test
+    public void testAddRemoveMembers() {
+        
+        Group group = new SimpleGroup("group");   
+        assertFalse(group.members().hasMoreElements());
+        
+        group.addMember(new SimpleGroup("group", "friend"));
+        
+        Enumeration<? extends Principal> members = group.members();
+        assertEquals(new SimpleGroup("group", "friend"), members.nextElement());
+        assertFalse(members.hasMoreElements());
+        
+        group.removeMember(new SimpleGroup("group", "friend"));
+        assertFalse(group.members().hasMoreElements());
+    }
+}

Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimpleGroupTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimpleGroupTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimplePrincipalTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimplePrincipalTest.java?rev=933326&view=auto
==============================================================================
--- cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimplePrincipalTest.java
(added)
+++ cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimplePrincipalTest.java
Mon Apr 12 17:07:19 2010
@@ -0,0 +1,39 @@
+/**
+ * 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.common.security;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SimplePrincipalTest extends Assert {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNullName() {
+        new SimplePrincipal(null);
+    }
+    
+    public void testEquals() {
+        assertEquals(new SimplePrincipal("barry"), new SimplePrincipal("barry"));
+    }
+    
+    public void testNotEquals() {
+        assertFalse(new SimplePrincipal("barry").equals(new SimplePrincipal("john")));
+    }
+}

Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimplePrincipalTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimplePrincipalTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 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=933326&r1=933325&r2=933326&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
(original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
Mon Apr 12 17:07:19 2010
@@ -19,6 +19,7 @@
 package org.apache.cxf.interceptor.security;
 
 import java.lang.reflect.Method;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.cxf.frontend.MethodDispatcher;
@@ -32,6 +33,9 @@ import org.apache.cxf.service.model.Bind
 
 public abstract class AbstractAuthorizingInInterceptor extends AbstractPhaseInterceptor<Message>
{
 
+    private static final String ALL_ROLES = "*";
+    
+    
     public AbstractAuthorizingInInterceptor() {
         super(Phase.PRE_INVOKE);
     }
@@ -44,17 +48,10 @@ public abstract class AbstractAuthorizin
         
         Method method = getTargetMethod(message);
         
-        List<String> expectedRoles = getExpectedRoles(method);
-        if (expectedRoles == null || expectedRoles.isEmpty()) {
+        if (authorize(sc, method)) {
             return;
         }
         
-        for (String role : expectedRoles) {
-            if (sc.isUserInRole(role)) {
-                return;
-            }
-        }
-        
         throw new AccessDeniedException("Unauthorized");
     }
     
@@ -65,5 +62,50 @@ public abstract class AbstractAuthorizin
         return md.getMethod(bop);
     }
 
+    protected boolean authorize(SecurityContext sc, Method method) {
+        List<String> expectedRoles = getExpectedRoles(method);
+        if (expectedRoles.isEmpty()) {
+            
+            List<String> denyRoles = getDenyRoles(method);
+            
+            return denyRoles.isEmpty() ? true : isUserInRole(sc, denyRoles, true);
+        }
+        
+        if (isUserInRole(sc, expectedRoles, false)) {
+            return true;
+        }
+        
+        return false;
+    }
+    
+    private boolean isUserInRole(SecurityContext sc, List<String> roles, boolean deny)
{
+        
+        if (roles.size() == 1 && ALL_ROLES.equals(roles.get(0))) {
+            return !deny;
+        }
+        
+        for (String role : roles) {
+            if (sc.isUserInRole(role)) {
+                return !deny;
+            }
+        }
+        return deny;
+    }
+    
+    /**
+     * Returns a list of expected roles for a given method. 
+     * @param method Method
+     * @return list, empty if no roles are available
+     */
     protected abstract List<String> getExpectedRoles(Method method);
+    
+       
+    /**
+     * Returns a list of roles to be denied for a given method. 
+     * @param method Method
+     * @return list, empty if no roles are available
+     */
+    protected List<String> getDenyRoles(Method method) {
+        return Collections.emptyList();
+    }
 }

Modified: 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=933326&r1=933325&r2=933326&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
(original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
Mon Apr 12 17:07:19 2010
@@ -19,23 +19,24 @@
 package org.apache.cxf.interceptor.security;
 
 import java.lang.reflect.Method;
+import java.util.Collections;
 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;
+    private Map<String, List<String>> methodRolesMap = Collections.emptyMap();
+    private List<String> globalRoles = Collections.emptyList();
     
     
     @Override
     protected List<String> getExpectedRoles(Method method) {
         List<String> roles = methodRolesMap.get(method.getName());
-        if (roles != null || classRolesMap == null) {
+        if (roles != null) {
             return roles;
         }
-        return methodRolesMap.get(method.getDeclaringClass().getName());
+        return globalRoles;
     }
 
 
@@ -44,8 +45,8 @@ public class SimpleAuthorizingIntercepto
         this.methodRolesMap = rolesMap;
     }
     
-    public void setClassRolesMap(Map<String, List<String>> rolesMap) {
-        this.classRolesMap = rolesMap;
+    public void setGlobalRoles(List<String> roles) {
+        globalRoles = roles;
     }
 
 

Added: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java?rev=933326&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
(added)
+++ cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
Mon Apr 12 17:07:19 2010
@@ -0,0 +1,173 @@
+/**
+ * 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.security.Principal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.cxf.frontend.MethodDispatcher;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.security.SecurityContext;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.BindingOperationInfo;
+import org.easymock.classextension.EasyMock;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SimpleAuthorizingInterceptorTest extends Assert {
+
+    private Method method;
+    private Message message = new MessageImpl();
+    
+    @Before
+    public void setUp() throws Exception {
+        method = TestService.class.getMethod("echo", new Class[]{});
+        message.put(SecurityContext.class, new TestSecurityContext());
+        Exchange ex = new ExchangeImpl();
+        message.setExchange(ex);
+        
+        Service service = EasyMock.createMock(Service.class);
+        ex.put(Service.class, service);
+        MethodDispatcher md = EasyMock.createMock(MethodDispatcher.class);
+        service.get(MethodDispatcher.class.getName());
+        EasyMock.expectLastCall().andReturn(md);
+        
+        BindingOperationInfo boi = EasyMock.createMock(BindingOperationInfo.class);
+        ex.put(BindingOperationInfo.class, boi);
+        md.getMethod(boi);
+        EasyMock.expectLastCall().andReturn(method);
+        EasyMock.replay(service, md);
+    }
+    
+    @Test
+    public void testPermitWithNoRoles() {
+        new SimpleAuthorizingInterceptor().handleMessage(message);    
+    }
+    
+    @Test
+    public void testPermitWithMethodRoles() {
+        SimpleAuthorizingInterceptor in = new SimpleAuthorizingInterceptor();
+        List<String> roles = new ArrayList<String>();
+        roles.add("role1");
+        roles.add("testRole");
+        in.setMethodRolesMap(Collections.singletonMap("echo", roles));
+        in.handleMessage(message);    
+    }
+    
+    @Test
+    public void testPermitAll() {
+        SimpleAuthorizingInterceptor in = new SimpleAuthorizingInterceptor();
+        List<String> roles = new ArrayList<String>();
+        roles.add("*");
+        in.setMethodRolesMap(Collections.singletonMap("echo", roles));
+        in.handleMessage(message);    
+    }
+    
+    @Test
+    public void testPermitWithClassRoles() {
+        SimpleAuthorizingInterceptor in = new SimpleAuthorizingInterceptor();
+        List<String> roles = new ArrayList<String>();
+        roles.add("role1");
+        roles.add("testRole");
+        in.setGlobalRoles(roles);
+        in.handleMessage(message);    
+    }
+    
+    @Test(expected = AccessDeniedException.class)
+    public void testDenyWithMethodRoles() {
+        SimpleAuthorizingInterceptor in = new SimpleAuthorizingInterceptor();
+        List<String> roles = new ArrayList<String>();
+        roles.add("role1");
+        roles.add("role2");
+        in.setMethodRolesMap(Collections.singletonMap("echo", roles));
+        in.handleMessage(message);    
+    }
+    
+    @Test(expected = AccessDeniedException.class)
+    public void testDenyWithClassRoles() {
+        SimpleAuthorizingInterceptor in = new SimpleAuthorizingInterceptor();
+        List<String> roles = new ArrayList<String>();
+        roles.add("role1");
+        roles.add("role2");
+        in.setGlobalRoles(roles);
+        in.handleMessage(message);    
+    }
+    
+    @Test
+    public void testPermitWithDenyRoles() {
+        SimpleAuthorizingInterceptor in = new SimpleAuthorizingInterceptor() {
+            @Override
+            public List<String> getDenyRoles(Method m) {
+                return Collections.singletonList("frogs");
+            }
+           
+        };
+        in.handleMessage(message);    
+    }
+    
+    @Test(expected = AccessDeniedException.class)
+    public void testDenyWithDenyRoles() {
+        SimpleAuthorizingInterceptor in = new SimpleAuthorizingInterceptor() {
+            @Override
+            public List<String> getDenyRoles(Method m) {
+                return Collections.singletonList("testRole");
+            }
+           
+        };
+        in.handleMessage(message);    
+    }
+    
+    @Test(expected = AccessDeniedException.class)
+    public void testDenyAll() {
+        SimpleAuthorizingInterceptor in = new SimpleAuthorizingInterceptor() {
+            @Override
+            public List<String> getDenyRoles(Method m) {
+                return Collections.singletonList("*");
+            }
+           
+        };
+        in.handleMessage(message);    
+    }
+    
+    private static class TestService {
+        public void echo() {
+            
+        }
+    }
+    
+    private static class TestSecurityContext implements SecurityContext {
+
+        public Principal getUserPrincipal() {
+            return null;
+        }
+
+        public boolean isUserInRole(String role) {
+            return "testRole".equals(role);
+        }
+        
+    }
+}

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

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

Modified: 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=933326&r1=933325&r2=933326&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
(original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
Mon Apr 12 17:07:19 2010
@@ -20,8 +20,6 @@ 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;
@@ -36,9 +34,9 @@ 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.phase.PhaseInterceptorChain;
 import org.apache.cxf.security.SecurityContext;
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSDocInfo;
@@ -77,7 +75,6 @@ public abstract class AbstractWSS4JSecur
     private static final Logger LOG = 
         LogUtils.getL7dLogger(AbstractWSS4JSecurityContextProvidingInterceptor.class);
     
-    private ThreadLocal<Message> messages = new ThreadLocal<Message>();
     private boolean supportDigestPasswords;
     
     public AbstractWSS4JSecurityContextProvidingInterceptor() {
@@ -92,48 +89,48 @@ public abstract class AbstractWSS4JSecur
         supportDigestPasswords = support;
     }
     
-    @Override
-    public void handleFault(SoapMessage m) {
-        messages.remove();
-        super.handleFault(m);
-    }
+    
     
     @Override
     protected SecurityContext createSecurityContext(final Principal p) {
-        Message msg = messages.get();
+        Message msg = PhaseInterceptorChain.getCurrentMessage();
         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;
-            }
-        };     
+        return doCreateSecurityContext(p, msg.get(Subject.class));
+    }
+    
+    /**
+     * Creates default SecurityContext which implements isUserInRole using the
+     * following approach : skip the first Subject principal, and then check optional
+     * Groups the principal is a member of. Subclasses can override this method and implement
+     * a custom strategy instead
+     *   
+     * @param p principal
+     * @param subject subject 
+     * @return security context
+     */
+    protected SecurityContext doCreateSecurityContext(final Principal p, final Subject subject)
{
+        return new DefaultSecurityContext(p, subject);
     }
 
+        
     protected void setSubject(String name, 
                               String password, 
                               boolean isDigest,
                               String nonce,
                               String created) throws WSSecurityException {
-        Message msg = messages.get();
+        Message msg = PhaseInterceptorChain.getCurrentMessage();
         if (msg == null) {
             throw new IllegalStateException("Current message is not available");
         }
-        Subject subject = createSubject(name, password, isDigest, nonce, created);
+        Subject subject = null;
+        try {
+            subject = createSubject(name, password, isDigest, nonce, created);
+        } catch (Exception ex) {
+            throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION, 
+                                          "Subject has not been created", null, ex);
+        }
         if (subject == null || subject.getPrincipals().size() == 0
             || !subject.getPrincipals().iterator().next().getName().equals(name)) {
             throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION, null,
null);
@@ -144,20 +141,21 @@ public abstract class AbstractWSS4JSecur
     /**
      * 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.
 
+     * and optionally followed by one or more principal Groups this user is a member of.
+     * It will also be available in doCreateSecurityContext.   
      * @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
+     * @throws SecurityException
      */
     protected abstract Subject createSubject(String name, 
                                     String password, 
                                     boolean isDigest,
                                     String nonce,
-                                    String created) throws WSSecurityException;
+                                    String created) throws SecurityException;
     
     
     /**
@@ -168,20 +166,16 @@ public abstract class AbstractWSS4JSecur
     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);
+        if ((doAction & WSConstants.UT) != 0 && !supportDigestPasswords) {  
 
+            CallbackHandler pwdCallback = null;
+            try {
+                pwdCallback = super.getCallback(reqData, doAction);
+            } catch (Exception ex) {
+                // ignore
             }
+            return new DelegatingCallbackHandler(pwdCallback);
         }
         
-        
         return super.getCallback(reqData, doAction);
     }
     
@@ -294,51 +288,4 @@ public abstract class AbstractWSS4JSecur
         }
     }
     
-    /**
-     * 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();
-        }
-    }
 }

Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContext.java?rev=933326&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContext.java
(added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContext.java
Mon Apr 12 17:07:19 2010
@@ -0,0 +1,76 @@
+/**
+ * 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.security.Principal;
+import java.security.acl.Group;
+import java.util.Enumeration;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.security.SecurityContext;
+
+/**
+ * SecurityContext which implements isUserInRole using the
+ * following approach : skip the first Subject principal, and then checks
+ * Groups the principal is a member of
+ * 
+ * TODO : consider moving this class into common/security
+ */
+public class DefaultSecurityContext implements SecurityContext {
+
+    private Principal p;
+    private Subject subject; 
+    
+    public DefaultSecurityContext(Principal p, Subject subject) {
+        this.p = p;
+        this.subject = subject;
+    }
+    
+    public Principal getUserPrincipal() {
+        return p;
+    }
+    public boolean isUserInRole(String role) {
+        if (subject == null || subject.getPrincipals().size() <= 1) {
+            return false;
+        }
+        for (Principal principal : subject.getPrincipals()) {
+            if (principal instanceof Group && checkGroup((Group)principal, role))
{ 
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean checkGroup(Group group, String role) {
+        if (group.getName().equals(role)) {
+            return true;
+        }
+            
+        for (Enumeration<? extends Principal> members = group.members(); members.hasMoreElements();)
{
+            // this might be a plain role but could represent a group consisting of the pther
groups/roles
+            Principal member = members.nextElement();
+            if (member.getName().equals(role) 
+                || member instanceof Group && checkGroup((Group)member, role)) {
+                return true;
+            }
+        }
+        return false;    
+    }
+}

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

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

Added: cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContextTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContextTest.java?rev=933326&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContextTest.java
(added)
+++ cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContextTest.java
Mon Apr 12 17:07:19 2010
@@ -0,0 +1,75 @@
+/**
+ * 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.security.Principal;
+import java.security.acl.Group;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.security.SimpleGroup;
+import org.apache.cxf.common.security.SimplePrincipal;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DefaultSecurityContextTest extends Assert {
+
+    @Test
+    public void testUserNotInRole() {
+        Subject s = new Subject();
+        Principal p = new SimplePrincipal("Barry");
+        s.getPrincipals().add(p);
+        assertFalse(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+    }
+    
+    @Test
+    public void testUserInRole() {
+        Subject s = new Subject();
+        Principal p = new SimplePrincipal("Barry");
+        s.getPrincipals().add(p);
+        s.getPrincipals().add(new SimpleGroup("friend", p));
+        assertTrue(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+    }
+    
+    @Test
+    public void testUserInRole2() {
+        Subject s = new Subject();
+        Principal p = new SimplePrincipal("Barry");
+        s.getPrincipals().add(p);
+        Group group = new SimpleGroup("Roles", p);
+        group.addMember(new SimpleGroup("friend"));
+        s.getPrincipals().add(group);
+        assertTrue(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+    }
+    
+    @Test
+    public void testUserInRole3() {
+        Subject s = new Subject();
+        Principal p = new SimplePrincipal("Barry");
+        s.getPrincipals().add(p);
+        Group group = new SimpleGroup("Roles", p);
+        Group subgroup = new SimpleGroup("subgroup");
+        subgroup.addMember(new SimpleGroup("friend"));
+        group.addMember(subgroup);
+        s.getPrincipals().add(group);
+        assertTrue(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+    }
+    
+}

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

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

Modified: 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=933326&r1=933325&r2=933326&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
(original)
+++ cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
Mon Apr 12 17:07:19 2010
@@ -20,7 +20,8 @@ package org.apache.cxf.ws.security.wss4j
 
 import javax.security.auth.Subject;
 
-import org.apache.ws.security.WSSecurityException;
+import org.apache.cxf.common.security.SimpleGroup;
+import org.apache.cxf.common.security.SimplePrincipal;
 
 public class SimpleSubjectCreatingInterceptor extends AbstractWSS4JSecurityContextProvidingInterceptor
{
 
@@ -29,7 +30,7 @@ public class SimpleSubjectCreatingInterc
                                     String password, 
                                     boolean isDigest,
                                     String nonce,
-                                    String created) throws WSSecurityException {
+                                    String created) throws SecurityException {
         Subject subject = new Subject();
          
         // delegate to the external security system if possible



Mime
View raw message