是的,你必须实现一个领域,但这并不难。您只需扩展 JndiLdapRealm 并覆盖 queryForAuthorizationInfo 方法。
此方法返回一个AuthorizationInfo 接口类型。在您的情况下,最简单的方法是返回实现此接口的SimpleAuthorizationInfo 实例。
您必须使用经过身份验证的用户的角色和/或权限初始化AuthorizationInfo。调用此方法时,用户已通过身份验证但未授权。
在此方法中,您可以从任何您想要的数据源读取授权信息,它可以是属性或 ini 文件、与 LDAP 服务器中的用户关联的属性、数据库或任何您喜欢的东西。
领域实现可以是:
package example.shiro.realm.ldap;
import javax.naming.NamingException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.ldap.JndiLdapRealm;
import org.apache.shiro.realm.ldap.LdapContextFactory;
import org.apache.shiro.subject.PrincipalCollection;
public class JndiLdapAuthzRealm extends JndiLdapRealm {
private List<String> getRoles(String userName) {
List<String> roles = new ArrayList<>();
// TODO: get roles from data source and fill list
roles.add("user");
roles.add("admin");
return roles;
}
private List<String> getPermissions(String userName) {
List<String> perms = new ArrayList<>();
// TODO: get permissions from data source and fill list
perms.add("myapp:run");
perms.add("myapp:file:create");
return perms;
}
@Override
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals,
LdapContextFactory ldapContextFactory) throws NamingException {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
String userName = principals.getPrimaryPrincipal().toString();
info.addRoles(getRoles(userName));
info.addStringPermissions(getPermissions(userName));
return info;
}
}
在您的情况下,重写 getRoles 和 getPermissions 以从属性或 ini 文件中获取经过身份验证的用户的角色和权限。
在shiro.ini:
[main]
ldapRealm = example.shiro.realm.ldap.JndiLdapAuthzRealm
ldapRealm.userDnTemplate = uid={0},cn=users,cn=accounts,dc=example,dc=com
ldapRealm.contextFactory.url = ldap://192.168.0.10