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.

Reply via email to