use*_*448 8 java authentication ldap vaadin shiro
你能帮我解决下列情况吗?
背景资料:
[主要]
contextFactory = org.apache.shiro.realm.ldap.JndiLdapContextFactory
contextFactory.url = ldaps://<SERVER>:636
contextFactory.systemUsername = <USERNAME>@<COMPANY>
contextFactory.systemPassword = <PASSWORD>
contextFactory.environment[java.naming.security.protocol] = ssl
realm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
realm.ldapContextFactory = $contextFactory
realm.searchBase = "OU=<APPDIR>,DC=<COMPANY>,DC=lcl"
realm.groupRolesMap = "CN=<ROLE>,OU=<APPDIR>,DC=<COMPANY>,DC=lcl":"Admin"
Run Code Online (Sandbox Code Playgroud)
[作用]
# 'Admin' role has permissions *
Admin = *
Run Code Online (Sandbox Code Playgroud)
目标
问题
问题
我使用 Shiro 1.2.4 遇到了类似的问题。您的 Shiro 配置可能没问题,问题出在 ActiveDirectory 配置上。
在我的设置中,一些用户设置了userPrincipalName属性,而其他用户则没有。例如,您可以使用Sysinternals Active Directory Explorer检查您的 AD 服务器。
Shiro 使用此属性来搜索特定用户,然后查找在memberOf属性中定义的组。
看一下ActiveDirectoryRealm.java源代码,Set<String> getRoleNamesForUser(String username, LdapContext ldapContext)
使用的确切查询方法是
String searchFilter = "(&(objectClass=*)(userPrincipalName={0}))";
所以你有两个解决方案:
我选择了第二种解决方案。更改搜索查询比应有的困难:您必须自定义类的queryForAuthorizationInfo
and getRoleNamesForUser
(因为它是私有的)方法ActiveDirectoryRealm
。我就是这样做的:
public class CustomActiveDirectoryRealm extends ActiveDirectoryRealm {
@Override
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException {
String username = (String) getAvailablePrincipal(principals);
// Perform context search
LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();
Set<String> roleNames = null;
try {
roleNames = getRoleNamesForUser(username, ldapContext);
} finally {
LdapUtils.closeContext(ldapContext);
}
return buildAuthorizationInfo(roleNames);
}
// Customize your search query here
private static final String USER_SEARCH_FILTER = "(&(objectClass=*)(sn={0}))";
private Set<String> getRoleNamesForUser(String username, LdapContext ldapContext) throws NamingException {
Set<String> roleNames;
roleNames = new LinkedHashSet<String>();
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String userPrincipalName = username.replace("acegas\\", "");
if (principalSuffix != null) {
userPrincipalName += principalSuffix;
}
Object[] searchArguments = new Object[]{userPrincipalName};
NamingEnumeration answer = ldapContext.search(searchBase, USER_SEARCH_FILTER, searchArguments, searchCtls);
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
Attributes attrs = sr.getAttributes();
if (attrs != null) {
NamingEnumeration ae = attrs.getAll();
while (ae.hasMore()) {
Attribute attr = (Attribute) ae.next();
if (attr.getID().equals("memberOf")) {
Collection<String> groupNames = LdapUtils.getAllAttributeValues(attr);
Collection<String> rolesForGroups = getRoleNamesForGroups(groupNames);
roleNames.addAll(rolesForGroups);
}
}
}
}
return roleNames;
}
}
Run Code Online (Sandbox Code Playgroud)
然后当然在shiro.ini中使用这个类作为Realm
[main]
realm = your.package.CustomActiveDirectoryRealm
realm.ldapContextFactory = $contextFactory
realm.searchBase = "OU=<APPDIR>,DC=<COMPANY>,DC=lcl"
realm.groupRolesMap = "CN=<ROLE>,OU=<APPDIR>,DC=<COMPANY>,DC=lcl":"Admin"
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2310 次 |
最近记录: |