Permalink
Browse files

JBAS-9289: add role mapping from jboss-web.xml

  • Loading branch information...
1 parent 8653297 commit 30ca6e3c631f1ff7ebf5151fe2d19ca6866186db @mmoyses mmoyses committed with bstansberry Apr 19, 2011
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright (c) 2011, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.as.testsuite.integration.websecurity;
+
+import java.net.URL;
+
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.api.Run;
+import org.jboss.arquillian.api.RunModeType;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit Test web security
+ *
+ * @author <a href="mailto:mmoyses@redhat.com">Marcus Moyses</a>
+ */
+@RunWith(Arquillian.class)
+@Run(RunModeType.AS_CLIENT)
+public class WebSecurityJBossWebXmlSecurityRolesTestCase extends WebSecurityFORMTestCase {
+
+ @Deployment
+ public static WebArchive deployment() {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ URL webxml = tccl.getResource("web-secure.war/web.xml");
+ WebArchive war = WebSecurityPasswordBasedBase.create("web-secure.war", SecuredServlet.class, true, webxml);
+
+ war.addResource(tccl.getResource("web-secure.war/login.jsp"), "login.jsp");
+ war.addResource(tccl.getResource("web-secure.war/error.jsp"), "error.jsp");
+ war.addResource(tccl.getResource("web-secure.war/jboss-web.xml"), "/WEB-INF/jboss-web.xml");
+
+ WebSecurityPasswordBasedBase.printWar(war);
+ return war;
+ }
+
+ /**
+ * Override test behavior to check if role mapping in jboss-web.xml works.
+ */
+ @Override
+ @Test
+ public void testPasswordBasedUnsuccessfulAuth() throws Exception {
+ makeCall("marcus", "marcus", 200);
+ }
+
+}
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<jboss-web>
+ <security-role>
+ <role-name>gooduser</role-name>
+ <principal-name>superuser</principal-name>
+ </security-role>
+</jboss-web>
@@ -28,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@@ -60,6 +61,7 @@
import org.jboss.security.AuthorizationManager;
import org.jboss.security.SecurityConstants;
import org.jboss.security.SecurityUtil;
+import org.jboss.security.mapping.MappingManager;
import org.jboss.util.loading.ContextClassLoaderSwitcher;
import org.jboss.util.loading.ContextClassLoaderSwitcher.SwitchContext;
import org.jboss.vfs.VirtualFile;
@@ -193,9 +195,15 @@ protected void processDeployment(final String hostName, final WarMetaData warMet
AuthorizationManager authzM = getAuthorizationManager(securityDomain);
realm.setAuthorizationManager(authzM);
+ MappingManager mapM = getMappingManager(securityDomain);
+ realm.setMappingManager(mapM);
+
+ Map<String, Set<String>> principalVersusRolesMap = metaData.getSecurityRoles().getPrincipalVersusRolesMap();
+ realm.setPrincipalVersusRolesMap(principalVersusRolesMap);
+
webContext.setRealm(realm);
- } catch (NamingException e1) {
- throw new RuntimeException(e1);
+ } catch (NamingException ne) {
+ throw new RuntimeException(ne);
} finally {
// restore previous tccl
switchContext.reset();
@@ -239,4 +247,9 @@ private AuthorizationManager getAuthorizationManager(String secDomain) throws Na
return (AuthorizationManager) ic.lookup(SecurityConstants.JAAS_CONTEXT_ROOT + secDomain + "/authorizationMgr");
}
+ private MappingManager getMappingManager(String secDomain) throws NamingException {
+ InitialContext ic = new InitialContext();
+ return (MappingManager) ic.lookup(SecurityConstants.JAAS_CONTEXT_ROOT + secDomain + "/mappingMgr");
+ }
+
}
@@ -26,6 +26,8 @@
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import javax.security.auth.Subject;
@@ -36,11 +38,15 @@
import org.jboss.security.AuthorizationManager;
import org.jboss.security.CertificatePrincipal;
import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityRolesAssociation;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.certs.SubjectDNMapping;
import org.jboss.security.callbacks.SecurityContextCallbackHandler;
import org.jboss.security.identity.Role;
import org.jboss.security.identity.RoleGroup;
+import org.jboss.security.mapping.MappingContext;
+import org.jboss.security.mapping.MappingManager;
+import org.jboss.security.mapping.MappingType;
/**
* A {@code RealmBase} implementation
@@ -65,6 +71,11 @@
protected AuthorizationManager authorizationManager = null;
/**
+ * The {@code MappingManager} instance to perform principal, role, attribute and credential mapping
+ */
+ protected MappingManager mappingManager = null;
+
+ /**
* Set the {@code AuthenticationManager}
*
* @param authenticationManager
@@ -83,10 +94,21 @@ public void setAuthorizationManager(AuthorizationManager authorizationManager) {
}
/**
+ * Set the {@code MappingManager}
+ *
+ * @param mappingManager
+ */
+ public void setMappingManager(MappingManager mappingManager) {
+ this.mappingManager = mappingManager;
+ }
+
+ /**
* The converter from X509 certificate chain to Principal
*/
protected CertificatePrincipal certMapping = new SubjectDNMapping();
+ protected Map<String, Set<String>> principalVersusRolesMap;
+
@Override
public Principal authenticate(String username, String credentials) {
if (username == null && credentials == null)
@@ -108,12 +130,28 @@ public Principal authenticate(String username, String credentials) {
sc.getUtil().createSubjectInfo(userPrincipal, credentials, subject);
SecurityActions.setSecurityContextOnAssociation(sc);
SecurityContextCallbackHandler scb = new SecurityContextCallbackHandler(sc);
+ if (mappingManager != null) {
+ // if there are mapping modules let them handle the role mapping
+ MappingContext<RoleGroup> mc = mappingManager.getMappingContext(MappingType.ROLE.name());
+ if (mc != null && mc.hasModules()) {
+ SecurityRolesAssociation.setSecurityRoles(principalVersusRolesMap);
+ }
+ }
RoleGroup roles = authorizationManager.getSubjectRoles(subject, scb);
List<Role> rolesAsList = roles.getRoles();
List<String> rolesAsStringList = new ArrayList<String>();
for (Role role : rolesAsList) {
rolesAsStringList.add(role.getRoleName());
}
+ if (mappingManager != null) {
+ // if there are no mapping modules handle role mapping here
+ MappingContext<RoleGroup> mc = mappingManager.getMappingContext(MappingType.ROLE.name());
+ if (mc == null || !mc.hasModules()) {
+ rolesAsStringList = mapUserRoles(rolesAsStringList);
+ }
+ }
+ else // if mapping manager is not set, handle role mapping here too
+ rolesAsStringList = mapUserRoles(rolesAsStringList);
return new GenericPrincipal(this, username, credentials, rolesAsStringList);
}
@@ -142,12 +180,28 @@ public Principal authenticate(X509Certificate[] certs) {
sc.getUtil().createSubjectInfo(userPrincipal, certs, subject);
SecurityActions.setSecurityContextOnAssociation(sc);
SecurityContextCallbackHandler scb = new SecurityContextCallbackHandler(sc);
+ if (mappingManager != null) {
+ // if there are mapping modules let them handle the role mapping
+ MappingContext<RoleGroup> mc = mappingManager.getMappingContext(MappingType.ROLE.name());
+ if (mc != null && mc.hasModules()) {
+ SecurityRolesAssociation.setSecurityRoles(principalVersusRolesMap);
+ }
+ }
RoleGroup roles = authorizationManager.getSubjectRoles(subject, scb);
List<Role> rolesAsList = roles.getRoles();
List<String> rolesAsStringList = new ArrayList<String>();
for (Role role : rolesAsList) {
rolesAsStringList.add(role.getRoleName());
}
+ if (mappingManager != null) {
+ // if there are no mapping modules handle role mapping here
+ MappingContext<RoleGroup> mc = mappingManager.getMappingContext(MappingType.ROLE.name());
+ if (mc == null || !mc.hasModules()) {
+ rolesAsStringList = mapUserRoles(rolesAsStringList);
+ }
+ }
+ else // if mapping manager is not set, handle role mapping here too
+ rolesAsStringList = mapUserRoles(rolesAsStringList);
userPrincipal = new GenericPrincipal(this, userPrincipal.getName(), null, rolesAsStringList);
} else {
if (log.isTraceEnabled()) {
@@ -176,4 +230,34 @@ protected String getPassword(String username) {
protected Principal getPrincipal(String username) {
return new SimplePrincipal(username);
}
+
+ public Map<String, Set<String>> getPrincipalVersusRolesMap() {
+ return principalVersusRolesMap;
+ }
+
+ public void setPrincipalVersusRolesMap(Map<String, Set<String>> principalVersusRolesMap) {
+ this.principalVersusRolesMap = principalVersusRolesMap;
+ }
+
+ protected List<String> mapUserRoles(List<String> rolesList) {
+ if (principalVersusRolesMap != null && principalVersusRolesMap.size() > 0) {
+ List<String> mappedRoles = new ArrayList<String>();
+ for (String role : rolesList) {
+ Set<String> roles = principalVersusRolesMap.get(role);
+ if (roles != null && roles.size() > 0) {
+ for (String r : roles) {
+ if (!mappedRoles.contains(r))
+ mappedRoles.add(r);
+ }
+ }
+ else {
+ if (!mappedRoles.contains(role))
+ mappedRoles.add(role);
+ }
+ }
+ return mappedRoles;
+ }
+
+ return rolesList;
+ }
}

0 comments on commit 30ca6e3

Please sign in to comment.