我在我的应用程序中有一个登录页面,在该页面中,我想根据Ldap AD验证输入的用户名/密码。我正在考虑创建一个绑定并获得一个上下文。如果bind成功,就意味着用户是经过身份验证的。在Java中,我实现了这样的目标:
public class Test {
public static void main(String[] args) {
try {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://ldapserver:389");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "domain\\userId"); //coming from frontend login form
env.put(Context.SECURITY_CREDENTIALS, password); // from login form
LdapContext ctx = new InitialLdapContext(env, null);
ctx.setRequestControls(null);
NamingEnumeration<?> namingEnum = ctx.search("ou=users,ou=in,dc=global,dc=company,dc=org", "(objectclass=user)", getSimpleSearchControls());
for (int i=0;i<1;i++) {
SearchResult result = (SearchResult) namingEnum.next();
Attributes attrs = result.getAttributes();
NamingEnumeration<String> nam =attrs.getIDs();
while(nam.hasMore()) {
System.out.println(nam.next());
}
}
namingEnum.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static SearchControls getSimpleSearchControls() {
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setTimeLimit(30000);
//String[] attrIDs = {"objectGUID"};
//searchControls.setReturningAttributes(attrIDs);
return searchControls;
}
}
上面的代码非常适合我。我希望在使用spring安全性的spring引导应用程序中实现相同的功能。我尝试过多种建议的方法,但每次都会出错。
在这里,我想验证enter用户名/密码,我认为上下文绑定就足够了,所以不需要再次使用"sAMAccountName={0}“之类的东西搜索该用户,如果我错了,请纠正我。
更新
在尝试下面的代码时,我可以在日志中看到它获取用户详细信息,但在最后一段中给出了一些错误:
auth
.ldapAuthentication()
.userSearchFilter("(sAMAccountName={0})")
.userDnPatterns()
.userSearchBase("dc=global,dc=company,dc=org")
.contextSource()
.url("ldap://ldapserver")
.port(389)
.managerDn("domain\\userId")
.managerPassword("******");
错误日志:
2022-08-04 19:47:44.477 TRACE 33541 --- [nio-8080-exec-2] o.s.s.w.a.www.BasicAuthenticationFilter : Found username 'userId' in Basic Authorization header
2022-08-04 19:47:44.478 TRACE 33541 --- [nio-8080-exec-2] o.s.s.authentication.ProviderManager : Authenticating request with LdapAuthenticationProvider (1/1)
2022-08-04 19:47:44.478 DEBUG 33541 --- [nio-8080-exec-2] o.s.s.l.a.LdapAuthenticationProvider : Processing authentication request for user: userId
2022-08-04 19:47:44.479 DEBUG 33541 --- [nio-8080-exec-2] o.s.s.l.s.FilterBasedLdapUserSearch : Searching for user 'userId', with user search [ searchFilter: '(sAMAccountName={0})', searchBase: 'dc=global,dc=company,dc=org', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
2022-08-04 19:47:44.831 DEBUG 33541 --- [nio-8080-exec-2] o.s.l.c.support.AbstractContextSource : Got Ldap context on server 'ldap://ldapserver'
2022-08-04 19:47:45.241 DEBUG 33541 --- [nio-8080-exec-2] o.s.s.ldap.SpringSecurityLdapTemplate : Searching for entry under DN '', base = 'dc=global,dc=company,dc=org', filter = '(sAMAccountName={0})'
2022-08-04 19:47:45.252 DEBUG 33541 --- [nio-8080-exec-2] o.s.s.ldap.SpringSecurityLdapTemplate : Found DN: CN=Kumar\, Rajesh,OU=Users,OU=IN,DC=global,DC=company,DC=org
2022-08-04 19:47:45.253 INFO 33541 --- [nio-8080-exec-2] o.s.s.ldap.SpringSecurityLdapTemplate : Ignoring PartialResultException
2022-08-04 19:47:45.254 DEBUG 33541 --- [nio-8080-exec-2] o.s.s.l.a.BindAuthenticator : Attempting to bind as cn=Kumar\, Rajesh,ou=Users,ou=IN,dc=global,dc=company,dc=org
2022-08-04 19:47:45.254 DEBUG 33541 --- [nio-8080-exec-2] s.s.l.DefaultSpringSecurityContextSource : Removing pooling flag for user cn=Kumar\, Rajesh,ou=Users,ou=IN,dc=global,dc=company,dc=org
2022-08-04 19:47:45.622 DEBUG 33541 --- [nio-8080-exec-2] o.s.l.c.support.AbstractContextSource : Got Ldap context on server 'ldap://ldapserver'
2022-08-04 19:47:45.623 DEBUG 33541 --- [nio-8080-exec-2] o.s.s.l.a.BindAuthenticator : Retrieving attributes... 2022-08-04 19:47:45.625 DEBUG 33541 --- [nio-8080-exec-2] .s.s.l.u.DefaultLdapAuthoritiesPopulator : Getting authorities for user cn=Kumar\, Rajesh,ou=Users,ou=IN,dc=global,dc=company,dc=org
2022-08-04 19:47:45.627 DEBUG 33541 --- [nio-8080-exec-2] .s.s.l.u.DefaultLdapAuthoritiesPopulator : Searching for roles for user 'userId', DN = 'cn=Kumar\, Rajesh,ou=Users,ou=IN,dc=global,dc= company,dc=org', with filter (uniqueMember={0}) in search base ''
2022-08-04 19:47:45.628 DEBUG 33541 --- [nio-8080-exec-2] o.s.s.ldap.SpringSecurityLdapTemplate : Using filter: (uniqueMember=cn=Kumar\5c, Rajesh,ou=Users,ou=IN,dc=global,dc= company,dc=org)
2022-08-04 19:47:45.628 DEBUG 33541 --- [nio-8080-exec-2] o.s.ldap.core.LdapTemplate : The returnObjFlag of supplied SearchControls is not set but a ContextMapper is used - setting flag to true
2022-08-04 19:47:45.629 DEBUG 33541 --- [nio-8080-exec-2] o.s.l.c.support.AbstractContextSource : Got Ldap context on server 'ldap://ldapserver'
2022-08-04 19:47:45.837 TRACE 33541 --- [nio-8080-exec-2] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match request to [Is Secure]
2022-08-04 19:47:45.838 DEBUG 33541 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-08-04 19:47:45.838 DEBUG 33541 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2022-08-04 19:47:45.839 TRACE 33541 --- [nio-8080-exec-2] o.s.b.w.s.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@1c138f13
2022-08-04 19:47:45.847 ERROR 33541 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.ldap.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-03100217, problem 2001 (NO_OBJECT), data 0, best match of: '' ];
nested exception is javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-03100217, problem 2001 (NO_OBJECT), data 0, best match of: '' ]; remaining name ''
at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:183) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:376) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:328) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:629) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:570) ~[spring-ldap-core-2.3.4.RELEASE.jar:2.3.4.RELEASE]
请有人引导我将这段普通的java代码迁移到spring安全性中。
问候
发布于 2022-08-05 16:57:48
我们可以在跟踪日志中看到以下消息:
DefaultLdapAuthoritiesPopulator : Searching for roles for user 'userId', DN = 'cn=Kumar\, Rajesh,ou=Users,ou=IN,dc=global,dc= company,dc=org', with filter (uniqueMember={0}) in search base ''
文件上说:
成功验证用户之后,LdapAuthenticationProvider将尝试通过调用配置的LdapAuthoritiesPopulator为用户加载一组权限。
默认实现是试图通过搜索用户所属组的目录来加载权限,但由于没有指定组搜索基,因此无法加载权限。
auth
.ldapAuthentication()
.userSearchFilter("(sAMAccountName={0})")
.userSearchBase("dc=global,dc=company,dc=org")
.groupSearchBase("dc=global,dc=company,dc=org") // <- here
.contextSource()
.url("ldap://ldapserver")
.port(389)
.managerDn("domain\\userId")
.managerPassword("******");
通常,这些组在目录树中的ou=Roles
组件下引用。例如,考虑到在“工作”代码:ou=roles,ou=in,dc=global,dc=company,dc=org
中定义的用户搜索基础,但是一个更大的基础(只有dc
)应该是可以的。
值得注意的是,您可以直接在ldap url中设置全局基,并为需要dn的参数定义相对dn (使用有效的全局基集,使groupSearchBase为空不会引发错误),例如:
.userSearchBase("ou=users,ou=in")
.groupSearchBase("ou=roles,ou=in")
有:
.url("ldap://ldapserver:389/dc=global,dc=company,dc=org")
另外,请注意,在使用userDnPatterns()
时不需要userSearchFilter()
,请使用其中一种或另一种。
@见Security文档:装载当局
https://stackoverflow.com/questions/73237295
复制相似问题