Hi all, if you are wondering how to map roles to permissions when authorizing against active directory then this post might help. (Do not be confused when reading 'versatec.invalid', it is simply the host and domain name we use for our internal network.) We use MongoDB as back end so this example retrieves the permissions from mongodb; if you use a different database just make sure you retrieve and return the permissions from your back end in the method '@Override public Collection<Permission> resolvePermissionsInRole(String roleString) ' Also, we use a multi-tenant approach for our applications which is *not in any way* required for active directory role to permission mapping to work, so feel free to ignore everything concerning 'tenant'.
shiro.ini: [main] ### active directory; without a searchBase a NullPointerException is thrown; Username must be an email address; cacerts.jks must contain certificate of active directory server for ldaps activeDirectoryRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm activeDirectoryRealm.searchBase = "CN=Users,DC=versatec,DC=invalid" activeDirectoryRealm.systemUsername = [email protected] activeDirectoryRealm.systemPassword = babaB4B4 activeDirectoryRealm.url = ldaps://localhost:636 activeDirectoryRealm.groupRolesMap = "CN=shiroGroup,CN=Users,DC=versatec,DC=invalid":"shiro" rolePermissionResolver = de.versatec.mongo.shiro.ActiveDirectoryRolePermissionResolver rolePermissionResolver.tenantId = versatec.invalid activeDirectoryRealm.rolePermissionResolver = $rolePermissionResolver ## the following filter is taken from BalusC's blog: http://balusc.blogspot.de/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html ajax = de.versatec.mongo.shiro.FacesAjaxAwareUserFilter ajax.loginUrl = /login.xhtml roles.unauthorizedUrl = /unauthorized.xhtml [urls] /login.xhtml = ssl[8181], ajax /samba.xhtml = ajax, perms["shiro:view"] ------------------------- ActiveDirectoryRolePermissionResolver.java: package de.versatec.mongo.shiro; import com.google.code.morphia.Datastore; import com.google.code.morphia.query.Query; import com.mongodb.MongoClient; import java.util.ArrayList; import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.naming.InitialContext; import javax.naming.NamingException; import org.apache.shiro.authz.Permission; import org.apache.shiro.authz.permission.RolePermissionResolver; public class ActiveDirectoryRolePermissionResolver implements RolePermissionResolver { private MongoProvider mongoProvider; private MongoClient mongoClient = null; private Datastore ds = null; private String tenantId = null; public ActiveDirectoryRolePermissionResolver() { // we retrieve our database connection here try { InitialContext initialContext = new InitialContext(); BeanManager bm = (BeanManager) initialContext.lookup("java:comp/BeanManager"); Bean<MongoProvider> bean = (Bean<MongoProvider>) bm.getBeans(MongoProvider.class).iterator().next(); CreationalContext<MongoProvider> ctx = bm.createCreationalContext(bean); mongoProvider = (MongoProvider) bm.getReference(bean, MongoProvider.class, ctx); if (mongoClient == null && mongoProvider != null) { mongoClient = mongoProvider.getMongoClient(); } if (ds == null && mongoProvider != null) { ds = mongoProvider.getDs(); } } catch (NamingException ex) { Logger.getLogger(MongoRealm.class.getName()).log(Level.SEVERE, null, ex); } } @Override public Collection<Permission> resolvePermissionsInRole(String roleString) { Collection<Permission> permissions = new ArrayList<>(); if (this.tenantId != null) { Query<Role> q = ds.createQuery(Role.class); q.field("name").equal(roleString); q.field("tenantId.identifier").equal(this.tenantId); Role role = q.get(); if (role != null) { permissions.addAll(role.getPermissions()); } } return permissions; } public String getTenantId() { return tenantId; } public void setTenantId(String tenantId) { this.tenantId = tenantId; } } ----------------------- Role.java: package de.versatec.mongo.shiro; import com.google.code.morphia.annotations.Embedded; import com.google.code.morphia.annotations.Entity; import com.google.code.morphia.annotations.Id; import java.util.HashSet; import java.util.Set; import org.apache.shiro.authz.Permission; import org.bson.types.ObjectId; @Entity public class Role { @Id private ObjectId id; private String name; private Set<Permission> permissions = new HashSet<>(); @Embedded private TenantId tenantId; public Role(String name) { this.name = name; } public Role() { } ... // getters and setters } -------------------- TenantId.java: package de.versatec.mongo.shiro; import com.google.code.morphia.annotations.Embedded; @Embedded public class TenantId { private String identifier; public TenantId(String identifier) { this.identifier = identifier; } public TenantId() { } public String getIdentifier() { return identifier; } public void setIdentifier(String identifier) { this.identifier = identifier; } } -- View this message in context: http://shiro-user.582556.n2.nabble.com/Example-Active-Directory-with-role-permission-mapping-tp7579030.html Sent from the Shiro User mailing list archive at Nabble.com.
