Return-Path: Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: (qmail 47603 invoked from network); 9 Feb 2011 21:36:27 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 9 Feb 2011 21:36:27 -0000 Received: (qmail 2032 invoked by uid 500); 9 Feb 2011 21:36:27 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 1946 invoked by uid 500); 9 Feb 2011 21:36:26 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 1939 invoked by uid 99); 9 Feb 2011 21:36:26 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 09 Feb 2011 21:36:26 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 09 Feb 2011 21:36:24 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 5506723889E3; Wed, 9 Feb 2011 21:36:04 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1069123 - in /cxf/trunk: api/src/main/java/org/apache/cxf/security/ rt/core/src/main/java/org/apache/cxf/interceptor/security/ rt/core/src/test/java/org/apache/cxf/interceptor/security/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/... Date: Wed, 09 Feb 2011 21:36:04 -0000 To: commits@cxf.apache.org From: sergeyb@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110209213604.5506723889E3@eris.apache.org> Author: sergeyb Date: Wed Feb 9 21:36:03 2011 New Revision: 1069123 URL: http://svn.apache.org/viewvc?rev=1069123&view=rev Log: [CXF-3322] Adding LoginSecurityContext interface Added: cxf/trunk/api/src/main/java/org/apache/cxf/security/LoginSecurityContext.java (with props) cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImplTest.java (with props) Removed: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContext.java Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImpl.java cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java Added: cxf/trunk/api/src/main/java/org/apache/cxf/security/LoginSecurityContext.java URL: http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/security/LoginSecurityContext.java?rev=1069123&view=auto ============================================================================== --- cxf/trunk/api/src/main/java/org/apache/cxf/security/LoginSecurityContext.java (added) +++ cxf/trunk/api/src/main/java/org/apache/cxf/security/LoginSecurityContext.java Wed Feb 9 21:36:03 2011 @@ -0,0 +1,46 @@ +/** + * 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.security; + +import java.security.Principal; +import java.util.Set; + +import javax.security.auth.Subject; + +/** + * LoginSecurityContext provides additional information about the + * authenticated principal. + * + * {@link SecurityContext} implementations which can get the authenticated + * Subject and/or the list of the user roles may implement this interface. + */ +public interface LoginSecurityContext extends SecurityContext { + + /** + * Returns the Subject representing the current authenticated user. + * @return the subject + */ + Subject getSubject(); + /** + * Returns a set of Principals representing the roles + * assigned to the current authenticated user Principal + * @return the roles + */ + Set getUserRoles(); +} Propchange: cxf/trunk/api/src/main/java/org/apache/cxf/security/LoginSecurityContext.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/api/src/main/java/org/apache/cxf/security/LoginSecurityContext.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java?rev=1069123&r1=1069122&r2=1069123&view=diff ============================================================================== --- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java (original) +++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java Wed Feb 9 21:36:03 2011 @@ -21,10 +21,12 @@ package org.apache.cxf.interceptor.secur import java.security.Principal; import java.security.acl.Group; import java.util.Enumeration; +import java.util.HashSet; +import java.util.Set; import javax.security.auth.Subject; -import org.apache.cxf.security.SecurityContext; +import org.apache.cxf.security.LoginSecurityContext; /** * SecurityContext which implements isUserInRole using the @@ -33,7 +35,7 @@ import org.apache.cxf.security.SecurityC * * TODO : consider moving this class into a rt-core-security module */ -public class DefaultSecurityContext implements SecurityContext { +public class DefaultSecurityContext implements LoginSecurityContext { private Principal p; private Subject subject; @@ -89,4 +91,22 @@ public class DefaultSecurityContext impl } return false; } + + @Override + public Subject getSubject() { + return subject; + } + + @Override + public Set getUserRoles() { + Set roles = new HashSet(); + if (subject != null) { + for (Principal principal : subject.getPrincipals()) { + if (principal != p) { + roles.add(principal); + } + } + } + return roles; + } } Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImpl.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImpl.java?rev=1069123&r1=1069122&r2=1069123&view=diff ============================================================================== --- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImpl.java (original) +++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImpl.java Wed Feb 9 21:36:03 2011 @@ -20,20 +20,23 @@ package org.apache.cxf.interceptor.security; import java.security.Principal; +import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.security.auth.Subject; -import org.apache.cxf.security.SecurityContext; +import org.apache.cxf.security.LoginSecurityContext; -public class RolePrefixSecurityContextImpl implements SecurityContext { +public class RolePrefixSecurityContextImpl implements LoginSecurityContext { private Principal p; - private Set roles; + private Set roles; + private Subject theSubject; public RolePrefixSecurityContextImpl(Subject subject, String rolePrefix) { this.p = findPrincipal(subject, rolePrefix); this.roles = findRoles(subject, rolePrefix); + this.theSubject = subject; } public Principal getUserPrincipal() { @@ -41,7 +44,14 @@ public class RolePrefixSecurityContextIm } public boolean isUserInRole(String role) { - return roles.contains(role); + // there is no guarantee the Principal instances retrieved + // from the Subject properly implement equalTo + for (Principal principal : roles) { + if (principal.getName().equals(role)) { + return true; + } + } + return false; } private static Principal findPrincipal(Subject subject, String rolePrefix) { @@ -53,13 +63,21 @@ public class RolePrefixSecurityContextIm return null; } - private static Set findRoles(Subject subject, String rolePrefix) { - Set set = new HashSet(); + private static Set findRoles(Subject subject, String rolePrefix) { + Set set = new HashSet(); for (Principal p : subject.getPrincipals()) { if (p.getName().startsWith(rolePrefix)) { - set.add(p.getName()); + set.add(p); } } - return set; + return Collections.unmodifiableSet(set); + } + + public Subject getSubject() { + return theSubject; + } + + public Set getUserRoles() { + return roles; } } \ No newline at end of file Modified: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java?rev=1069123&r1=1069122&r2=1069123&view=diff ============================================================================== --- cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java (original) +++ cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java Wed Feb 9 21:36:03 2011 @@ -20,11 +20,14 @@ package org.apache.cxf.interceptor.secur import java.security.Principal; import java.security.acl.Group; +import java.util.HashSet; +import java.util.Set; import javax.security.auth.Subject; import org.apache.cxf.common.security.SimpleGroup; import org.apache.cxf.common.security.SimplePrincipal; +import org.apache.cxf.security.LoginSecurityContext; import org.junit.Assert; import org.junit.Test; @@ -49,6 +52,32 @@ public class DefaultSecurityContextTest } @Test + public void testMultipleRoles() { + Subject s = new Subject(); + Principal p = new SimplePrincipal("Barry"); + s.getPrincipals().add(p); + + Set roles = new HashSet(); + roles.add(new SimpleGroup("friend", p)); + roles.add(new SimpleGroup("admin", p)); + s.getPrincipals().addAll(roles); + + LoginSecurityContext context = new DefaultSecurityContext(p, s); + assertTrue(context.isUserInRole("friend")); + assertTrue(context.isUserInRole("admin")); + assertFalse(context.isUserInRole("bar")); + + Set roles2 = context.getUserRoles(); + assertEquals(roles2, roles); + } + + @Test + public void testGetSubject() { + Subject s = new Subject(); + assertSame(new DefaultSecurityContext(s).getSubject(), s); + } + + @Test public void testUserInRole2() { Subject s = new Subject(); Principal p = new SimplePrincipal("Barry"); Added: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImplTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImplTest.java?rev=1069123&view=auto ============================================================================== --- cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImplTest.java (added) +++ cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImplTest.java Wed Feb 9 21:36:03 2011 @@ -0,0 +1,79 @@ +/** + * 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.security.Principal; +import java.util.HashSet; +import java.util.Set; + +import javax.security.auth.Subject; + +import org.apache.cxf.common.security.SimplePrincipal; +import org.apache.cxf.security.LoginSecurityContext; + +import org.junit.Assert; +import org.junit.Test; + +public class RolePrefixSecurityContextImplTest extends Assert { + + @Test + public void testUserNotInRole() { + Subject s = new Subject(); + Principal p = new SimplePrincipal("Barry"); + s.getPrincipals().add(p); + assertFalse(new RolePrefixSecurityContextImpl(s, "").isUserInRole("friend")); + } + + @Test + public void testUserInRole() { + Subject s = new Subject(); + Principal p = new SimplePrincipal("Barry"); + s.getPrincipals().add(p); + s.getPrincipals().add(new SimplePrincipal("role_friend")); + assertTrue(new RolePrefixSecurityContextImpl(s, "role_") + .isUserInRole("role_friend")); + } + + @Test + public void testMultipleRoles() { + Subject s = new Subject(); + Principal p = new SimplePrincipal("Barry"); + s.getPrincipals().add(p); + + Set roles = new HashSet(); + roles.add(new SimplePrincipal("role_friend")); + roles.add(new SimplePrincipal("role_admin")); + s.getPrincipals().addAll(roles); + + LoginSecurityContext context = new RolePrefixSecurityContextImpl(s, "role_"); + assertTrue(context.isUserInRole("role_friend")); + assertTrue(context.isUserInRole("role_admin")); + assertFalse(context.isUserInRole("role_bar")); + + Set roles2 = context.getUserRoles(); + assertEquals(roles2, roles); + } + + @Test + public void testGetSubject() { + Subject s = new Subject(); + assertSame(new RolePrefixSecurityContextImpl(s, "").getSubject(), s); + } + +} Propchange: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImplTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/RolePrefixSecurityContextImplTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java?rev=1069123&r1=1069122&r2=1069123&view=diff ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java (original) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java Wed Feb 9 21:36:03 2011 @@ -38,19 +38,26 @@ import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; import org.w3c.dom.Document; import org.apache.cxf.jaxrs.ext.xml.XMLSource; +import org.apache.cxf.jaxrs.utils.HttpUtils; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.PhaseInterceptorChain; +import org.apache.cxf.staxutils.StaxSource; import org.apache.cxf.staxutils.StaxUtils; @Provider @Produces({"application/xml", "application/*+xml", "text/xml" }) @Consumes({"application/xml", "application/*+xml", "text/xml", "text/html" }) -public class SourceProvider implements +public class SourceProvider extends AbstractConfigurableProvider implements MessageBodyReader, MessageBodyWriter { + private static final String PREFERRED_FORMAT = "source-preferred-format"; + public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mt) { return Source.class.isAssignableFrom(type); } @@ -64,9 +71,18 @@ public class SourceProvider implements public Object readFrom(Class source, Type genericType, Annotation[] annotations, MediaType m, MultivaluedMap headers, InputStream is) throws IOException { - if (DOMSource.class.isAssignableFrom(source) || Document.class.isAssignableFrom(source)) { + + Class theSource = source; + if (theSource == Source.class) { + String s = getPreferredSource(); + if ("sax".equalsIgnoreCase(s) || "cxf.stax".equalsIgnoreCase(s)) { + theSource = SAXSource.class; + } + } + + if (DOMSource.class.isAssignableFrom(theSource) || Document.class.isAssignableFrom(theSource)) { - boolean docRequired = Document.class.isAssignableFrom(source); + boolean docRequired = Document.class.isAssignableFrom(theSource); XMLStreamReader reader = StaxUtils.createXMLStreamReader(is); try { Document doc = StaxUtils.read(reader); @@ -82,21 +98,34 @@ public class SourceProvider implements //ignore } } - } else if (StreamSource.class.isAssignableFrom(source) - || Source.class.isAssignableFrom(source)) { + } else if (SAXSource.class.isAssignableFrom(theSource) + || StaxSource.class.isAssignableFrom(theSource)) { + return new StaxSource(StaxUtils.createXMLStreamReader(is)); + } + else if (StreamSource.class.isAssignableFrom(theSource) + || Source.class.isAssignableFrom(theSource)) { return new StreamSource(is); - } else if (XMLSource.class.isAssignableFrom(source)) { + } else if (XMLSource.class.isAssignableFrom(theSource)) { return new XMLSource(is); } throw new IOException("Unrecognized source"); } + protected String getPreferredSource() { + Message m = PhaseInterceptorChain.getCurrentMessage(); + if (m != null) { + return (String)m.getContextualProperty(PREFERRED_FORMAT); + } else { + return "sax"; + } + } + public void writeTo(Source source, Class clazz, Type genericType, Annotation[] annotations, - MediaType m, MultivaluedMap headers, OutputStream os) + MediaType mt, MultivaluedMap headers, OutputStream os) throws IOException { - String encoding = "utf-8"; //FIXME + String encoding = HttpUtils.getSetEncoding(mt, headers, "UTF-8"); XMLStreamReader reader = StaxUtils.createXMLStreamReader(source); XMLStreamWriter writer = StaxUtils.createXMLStreamWriter(os, encoding);