cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r933329 - in /cxf/branches/2.2.x-fixes: ./ 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/j...
Date Mon, 12 Apr 2010 17:20:12 GMT
Author: sergeyb
Date: Mon Apr 12 17:20:11 2010
New Revision: 933329

URL: http://svn.apache.org/viewvc?rev=933329&view=rev
Log:
Merged revisions 933326 via svnmerge from 
https://svn.apache.org/repos/asf/cxf/trunk

........
  r933326 | sergeyb | 2010-04-12 18:07:19 +0100 (Mon, 12 Apr 2010) | 1 line
  
  CXF-2754,CXF-2755: some refactoring, adding unit tests
........

Added:
    cxf/branches/2.2.x-fixes/common/common/src/main/java/org/apache/cxf/common/security/
      - copied from r933326, cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/
    cxf/branches/2.2.x-fixes/common/common/src/main/java/org/apache/cxf/common/security/SimpleGroup.java
      - copied unchanged from r933326, cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimpleGroup.java
    cxf/branches/2.2.x-fixes/common/common/src/main/java/org/apache/cxf/common/security/SimplePrincipal.java
      - copied unchanged from r933326, cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SimplePrincipal.java
    cxf/branches/2.2.x-fixes/common/common/src/test/java/org/apache/cxf/common/security/
      - copied from r933326, cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/
    cxf/branches/2.2.x-fixes/common/common/src/test/java/org/apache/cxf/common/security/SimpleGroupTest.java
      - copied unchanged from r933326, cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimpleGroupTest.java
    cxf/branches/2.2.x-fixes/common/common/src/test/java/org/apache/cxf/common/security/SimplePrincipalTest.java
      - copied unchanged from r933326, cxf/trunk/common/common/src/test/java/org/apache/cxf/common/security/SimplePrincipalTest.java
    cxf/branches/2.2.x-fixes/rt/core/src/test/java/org/apache/cxf/interceptor/security/
      - copied from r933326, cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/
    cxf/branches/2.2.x-fixes/rt/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
      - copied unchanged from r933326, cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
    cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContext.java
      - copied unchanged from r933326, cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContext.java
    cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContextTest.java
      - copied unchanged from r933326, cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContextTest.java
Modified:
    cxf/branches/2.2.x-fixes/   (props changed)
    cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
    cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
    cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
    cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java

Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
    svn:mergeinfo = /cxf/trunk:933326

Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java?rev=933329&r1=933328&r2=933329&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
(original)
+++ cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
Mon Apr 12 17:20:11 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/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java?rev=933329&r1=933328&r2=933329&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
(original)
+++ cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
Mon Apr 12 17:20:11 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;
     }
 
 

Modified: cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java?rev=933329&r1=933328&r2=933329&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
(original)
+++ cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JSecurityContextProvidingInterceptor.java
Mon Apr 12 17:20:11 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();
-        }
-    }
 }

Modified: cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java?rev=933329&r1=933328&r2=933329&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
(original)
+++ cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/SimpleSubjectCreatingInterceptor.java
Mon Apr 12 17:20:11 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