Spring Security Spring LDAP返回相同且不正确的objectSid

c9qzyr3d  于 2023-08-05  发布在  Spring
关注(0)|答案(3)|浏览(122)

在我的Spring Web应用程序中,我无法从使用Active Directory帐户的当前登录用户中检索正确的objectId。所有的属性似乎都有正确的值,但是objectId的值总是设置为S-1-5-21-1723711471-3183472479-4012130053-3220159935,我不知道它来自哪里。

WebSecurityConfig

  1. @Configuration
  2. @EnableWebSecurity
  3. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  4. @Override
  5. protected void configure(HttpSecurity http) throws Exception {
  6. http
  7. .authorizeRequests()
  8. .antMatchers("/", "/home").permitAll()
  9. .anyRequest().authenticated()
  10. .and()
  11. .formLogin()
  12. .loginPage("/login")
  13. .permitAll()
  14. .and()
  15. .logout()
  16. .permitAll();
  17. }
  18. @Override
  19. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  20. auth
  21. .authenticationProvider(activeDirectoryLdapAuthenticationProvider());
  22. }
  23. private ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
  24. ActiveDirectoryLdapAuthenticationProvider provider =
  25. new ActiveDirectoryLdapAuthenticationProvider(LdapConfig.AD_DOMAIN, LdapConfig.AD_SERVER);
  26. provider.setUserDetailsContextMapper(new LdapUserDetailsContextMapper());
  27. return provider;
  28. }
  29. }

字符串

LdapUserDetailsContextMapper

  1. @Slf4j
  2. public class LdapUserDetailsContextMapper implements UserDetailsContextMapper {
  3. @Override
  4. public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> collection) {
  5. log.info("username: " + username); //username is correct
  6. log.info("DN from ctx: " + ctx.getDn()); // returns correct DN
  7. byte[] byteSid = ctx.getStringAttribute("objectSid").getBytes();
  8. String sid = LdapUtils.convertBinarySidToString(byteSid);
  9. log.info("SID: " + sid); // S-1-5-21-1723711471-3183472479-4012130053-3220159935 everytime
  10. return new User(username, "notUsed", true, true, true, true,
  11. AuthorityUtils.createAuthorityList("ROLE_USER"));
  12. }
  13. @Override
  14. public void mapUserToContext(UserDetails userDetails, DirContextAdapter dirContextAdapter) {
  15. }
  16. }


如何从Active Directory中获取正确的SID?

hkmswyz6

hkmswyz61#

我想答案就在这里:http://forum.spring.io/forum/spring-projects/data/ldap/66894-objectsid-and-ldaptemplate
在第二个最后一个帖子中,他描述了你遇到的同样的问题。在上一篇文章中,他描述了一个修复方法,即将此添加到Bean配置文件中:

  1. <bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
  2. <property name="url" value="ldap://ldapserver.domain.com:389" />
  3. <property name="base" value="dc=domain,dc=com" />
  4. <property name="userDn" value="cn=binduser,cn=Users,dc=domain,dc=com" />
  5. <property name="password" value="bindpwd"/>
  6. <property name="baseEnvironmentProperties">
  7. <map>
  8. <entry key="java.naming.ldap.attributes.binary">
  9. <value>objectSid</value>
  10. </entry>
  11. </map>
  12. </property>
  13. </bean>

字符串
您必须修改域的值,但我认为重要的部分是baseEnvironmentProperties
This thread还描述了一种编程方式来设置该属性(尽管对于objectGuid,但您可以只交换该属性)。

  1. AbstractContextSource contextSource = (AbstractContextSource) ldapTemplate.getContextSource();
  2. Map<String,String> baseEnvironmentProperties = new HashMap<String, String>();
  3. baseEnvironmentProperties.put("java.naming.ldap.attributes.binary", "objectSid");
  4. contextSource.setBaseEnvironmentProperties(baseEnvironmentProperties);
  5. contextSource.afterPropertiesSet();

展开查看全部
5ssjco0h

5ssjco0h2#

我通过在configure方法中添加环境属性来实现这一点:

  1. @Configuration
  2. @EnableWebSecurity
  3. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  4. @Override
  5. protected void configure(HttpSecurity http) throws Exception {
  6. http
  7. .authorizeRequests()
  8. .antMatchers("/", "/home").permitAll()
  9. .anyRequest().authenticated()
  10. .and()
  11. .formLogin()
  12. .loginPage("/login")
  13. .permitAll()
  14. .and()
  15. .logout()
  16. .permitAll();
  17. }
  18. @Override
  19. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  20. auth
  21. .authenticationProvider(activeDirectoryLdapAuthenticationProvider());
  22. }
  23. private ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
  24. ActiveDirectoryLdapAuthenticationProvider provider =
  25. new ActiveDirectoryLdapAuthenticationProvider(LdapConfig.AD_DOMAIN, LdapConfig.AD_SERVER);
  26. // ************** NEW ENVIRONMENT PROPERTIES **********************************
  27. Map<String, Object> environmentProperties = new HashMap<>();
  28. environmentProperties.put("java.naming.ldap.attributes.binary", "objectsid");
  29. provider.setContextEnvironmentProperties(environmentProperties);
  30. // ************** END OF NEW ENVIRONMENT PROPERTIES ***************************
  31. provider.setUserDetailsContextMapper(new LdapUserDetailsContextMapper());
  32. return provider;
  33. }
  34. }

字符串
然后在UserDetailContextMapper中像这样阅读它:

  1. public class CustomUserDetailsContextMapper implements UserDetailsContextMapper {
  2. private final static Logger logger = LoggerFactory.getLogger(CustomUserDetailsContextMapper.class);
  3. @Override
  4. public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
  5. logger.info(ctx.getDn().toString());
  6. byte[] byteSid = null;
  7. try {
  8. byteSid = (byte[]) ctx.getAttributes().get("objectsid").get();
  9. } catch (NamingException e) {
  10. e.printStackTrace();
  11. }
  12. String sid = LdapUtils.convertBinarySidToString(byteSid);
  13. logger.info("SID: {}", sid);
  14. return new User(username, "notUsed", true, true, true, true,
  15. AuthorityUtils.createAuthorityList("ROLE_USER"));
  16. }


我希望这是有帮助的!

展开查看全部
dgenwo3n

dgenwo3n3#

这不是关于Spring的,而是关于普通的JavaLDAP访问(以防有人发现这个页面在寻找它--就像我一样)。在构建DirContext时,需要告诉它将objectSid保持为二进制形式。否则,它将尝试将字节解码为String,这将用unicode REPLACEMENT CHARACTER U+FFFD(�)替换无效字符-从而无法获得正确的Sid。

  1. DirContext ldapConnect() throws NamingException {
  2. Hashtable<String, String> env = new Hashtable<>();
  3. env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
  4. env.put(Context.PROVIDER_URL, ldapServer);
  5. env.put(Context.SECURITY_AUTHENTICATION, "simple");
  6. env.put(Context.SECURITY_PRINCIPAL, ldapUser);
  7. env.put(Context.SECURITY_CREDENTIALS, ldapPassword);
  8. env.put("java.naming.ldap.attributes.binary", "objectSid"); // !!!!!!!!!!!!!!!!!!
  9. return new InitialDirContext(env);
  10. }

字符串
这基本上是Gabriel Lucis的答案,只是为了香草Java而不是Spring。

展开查看全部

相关问题