我正在使用Shiro使用ActiveDirectoryRealm
对Active Directory进行身份验证。这部分工作正常,我可以登录。
但是,我无法搜索角色/群组。
我怀疑是因为我没有配置systemUsername/systemPassword
。我也没有这个选择。
如果我使用像LdapAdmin这样的应用程序,我必须将我的电子邮件和密码放在身份验证字段中才能连接和浏览。
当我使用Spring Security时,我不必提供任何此类“systemUser”。我猜它使用了我提供的相同用户名/密码凭据来登录。
如何配置Shiro执行相同操作?
请参阅下文,了解我的shiro.ini
的粗略版本。
adRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
adRealm.url = ldap://my.ad.url:389
adRealm.principalSuffix=@example.com
adRealm.systemUsername=
adRealm.systemPassword=
adRealm.searchBase = "OU=org,DC=example,DC=com"
adRealm.groupRolesMap = "CN=admins":"admin"
答案 0 :(得分:0)
目前它不支持这一点。
当检查验证时,可以改进当前实现以查询角色信息。 (这是领域可以访问用户凭据的唯一点)
答案 1 :(得分:0)
正如评论中所建议的,我创建了一个自定义域(扩展ActiveDirectoryRealm)以在登录期间搜索角色,然后直接访问它们,而不是尝试使用系统用户进行搜索。
下面是突出的代码,完整代码在GitHub上。
/**
* This is called during the log in process.
* Authenticate but also store the roles/groups on a custom principal
*/
@Override
protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {
SimpleAuthenticationInfo authenticationInfo = (SimpleAuthenticationInfo)super.queryForAuthenticationInfo(token, ldapContextFactory);
PrincipalCollection principals = authenticationInfo.getPrincipals();
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;
String username = usernamePasswordToken.getUsername();
String userPrincipalName = getUserPrincipalName(token);
Set<String> roleNames;
// Binds using the username and password provided by the user.
LdapContext ldapContext = null;
try {
ldapContext = ldapContextFactory.getLdapContext(userPrincipalName, (usernamePasswordToken.getPassword()));
roleNames = getRoleNamesForUser(username, ldapContext);
} finally {
LdapUtils.closeContext(ldapContext);
}
List<UserPrincipal> customPrincipals = getCustomPrincipals(userPrincipalName, roleNames);
//Merge the custom principals and the main principals
SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(customPrincipals, CustomActiveDirectoryRealm.class.getSimpleName());
principalCollection.addAll(principals);
authenticationInfo.setPrincipals(principalCollection);
return authenticationInfo;
}
/**
* This is called during checks for hasRole.
* Use the roles that we found on login
*/
@Override
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException {
UserPrincipal availablePrincipal = (UserPrincipal)getAvailablePrincipal(principals);
Set<String> roleNames = availablePrincipal.getRoleNames();
return buildAuthorizationInfo(roleNames);
}