如何使用带有 LDAP 身份验证的 Apache Shiro 添加角色授权

Posted

技术标签:

【中文标题】如何使用带有 LDAP 身份验证的 Apache Shiro 添加角色授权【英文标题】:How to add role authorization using Apache Shiro with LDAP Authentication 【发布时间】:2018-02-22 05:04:30 【问题描述】:

我是 Apache Shiro 和 LDAP 的新手。 我正在尝试使用 Apache shiro 创建一个简单的 LDAP 身份验证。身份验证有效,但我无法向用户添加角色。下面是我正在使用的 shiro.ini 文件:

[main]
realm = org.apache.shiro.realm.ldap.JndiLdapRealm
realm.contextFactory.url = ldap://localhost:389
contextFactory = org.apache.shiro.realm.ldap.JndiLdapContextFactory
contextFactory.systemUsername = cn=Manager,dc=maxcrc,dc=com
contextFactory.systemPassword = secret
[roles]
People = *
role = *
Administrator = *

下面是java类文件:

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;

import java.util.ArrayList;
import java.util.List;

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 LDAPTest extends JndiLdapRealm 


public static final String userName = "uid=aarippa,ou=People,dc=maxcrc,dc=com";
//public static final String userName = "uid=arjunarippa";
public static final String password = "SomePassword";

public static void main(String[] args)

    Factory<SecurityManager> factory = new IniSecurityManagerFactory("N:\\workspace\\LdapAuthentication\\src\\auth.ini");
    SecurityManager securityManager = factory.getInstance();
    SecurityUtils.setSecurityManager( securityManager );
    System.out.println( "userName is  : " +userName);
    System.out.println( "password is  : " +password);
    //UsernamePasswordToken token = new UsernamePasswordToken( "cn=Panji Pratomo,ou=people,dc=maxcrc,dc=com", "SomePassword" );
    UsernamePasswordToken token = new UsernamePasswordToken( userName,password );
    Subject currentUser = SecurityUtils.getSubject();
    //System.out.println(currentUser);

    try
    
        currentUser.login( token );
        System.out.println( "We've authenticated! :)" );
    
    catch ( AuthenticationException e )
    
        System.out.println( "We did not authenticate :(" );
        e.printStackTrace();
    


    if ( currentUser.hasRole( "people" ) )
    
        System.out.println( "We have the role! :)" );
    
    else
    
        System.out.println( "We do not have the role :(" );
    
    if ( currentUser.isPermitted( "foo.blah" ) )
    
        System.out.println( "We're authorized! :)" );
    
    else
    
        System.out.println( "We are not authorized :(" );
    


我无法理解如何为用户添加角色。身份验证工作正常,但收到错误消息“我们没有角色:(”和“我们没有被授权:(” 目前我正在使用 OpenLDAP 服务器,下面是我在服务器中创建的一个 .LDIF 条目:

dn: uid=aarippa,ou=people,dc=maxcrc,dc=com
objectclass: inetOrgPerson
cn: Arjun Arippa
cn: A Arippa
cn: Aarippa
sn: fahmi
uid: aarippa
userpassword: SomePassword
carlicense: HISCAR 123
homephone: 555-111-2222
mail: f.satrio222@gmail.com
mail: f.satrio222@mysamz.com
mail: guest108222@fif.co.id
description: tukang ngulik ga jelas
ou: SOA

如果我通过添加正确的角色做了正确的事情,任何人都可以告诉我,如果有错,请纠正我。我在编写的方法中遗漏了什么吗?

谢谢, 阿琼

【问题讨论】:

【参考方案1】:

开箱即用的通用 LDAPRealm 不处理角色。 Active Directory 领域可以(如果您在 AD 上)。否则,您可以扩展领域并实现doGetAuthorizationInfo 方法。 尽管有一些常见的策略,但几乎可以通过多种方式配置 LDAP 服务器。您的用户如何与您的群组相关联?您有示例查询或示例组记录吗?

【讨论】:

最初我是否可以使用 LDAP 领域。但是在看到您的评论后,我尝试使用 AD Realm(因为我仍然不确定要求是使用 LDAPRealm 还是 ADRealm)。所以我正在尝试使用 ADRealm 进行身份验证和角色授权。但是,我收到一个错误:Exception in thread "main" org.apache.shiro.authz.AuthorizationException: LDAP naming error while attempting to retrieve authorization for user [uid=aarippa,ou=people,dc=maxcrc,dc=com]. at org.apache.shiro.realm.ldap.AbstractLdapRealm.doGetAuthorizationInfo(AbstractLdapRealm.java:210) 以下是我在 OpenLDAP 服务器中的条目:dn: uid=aarippa,ou=people,dc=maxcrc,dc=com objectclass: inetOrgPerson cn: Arjun Arippa cn: A Arippa cn: Aarippa sn: fahmi uid: aarippa userpassword: SomePassword carlicense: HISCAR 123 homephone: 555-111-2222 mail: f.satrio222@gmail.com mail: f.satrio222@mysamz.com mail: guest108222@fif.co.id description: tukang ngulik ga jelas ou: SOA 下面是我在 shiro.ini 文件中创建的条目:activeDirectoryRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm activeDirectoryRealm.searchBase = "ou=People,dc=maxcrc,dc=com" activeDirectoryRealm.systemUsername = manager activeDirectoryRealm.systemPassword = secret activeDirectoryRealm.url = ldap://localhost:389 activeDirectoryRealm.groupRolesMap = "ou=People,dc=maxcrc,dc=com":"sysadmin" securityManager.realm = $activeDirectoryRealm activeDirectoryRealm.authorizationCachingEnabled = false

以上是关于如何使用带有 LDAP 身份验证的 Apache Shiro 添加角色授权的主要内容,如果未能解决你的问题,请参考以下文章

LDAP 身份验证不适用于 websvn

使用apache LDAP在java中进行LDAP身份验证

Apache Shiro - 用于身份验证和属性的 LDAP/用于授权的 Ini

如何使用 Spring Ldap Authentication 和 spring mvc 对用户进行身份验证

在 Apache Shiro 中使用 ActiveDirectoryRealm 时如何搜索 ldap 字段?

Apache LDAP 身份验证仅适用于某些虚拟主机