在我的Spring Web应用程序中,我无法使用Active Directory帐户从当前登录的用户中检索正确的objectId
。所有属性似乎都具有正确的值,但objectId
值始终设置为S-1-5-21-1723711471-3183472479-4012130053-3220159935
,我不知道它来自何处。
WebSecurityConfig
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
private ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider =
new ActiveDirectoryLdapAuthenticationProvider(LdapConfig.AD_DOMAIN, LdapConfig.AD_SERVER);
provider.setUserDetailsContextMapper(new LdapUserDetailsContextMapper());
return provider;
}
}
LdapUserDetailsContextMapper
@Slf4j
public class LdapUserDetailsContextMapper implements UserDetailsContextMapper {
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> collection) {
log.info("username: " + username); //username is correct
log.info("DN from ctx: " + ctx.getDn()); // returns correct DN
byte[] byteSid = ctx.getStringAttribute("objectSid").getBytes();
String sid = LdapUtils.convertBinarySidToString(byteSid);
log.info("SID: " + sid); // S-1-5-21-1723711471-3183472479-4012130053-3220159935 everytime
return new User(username, "notUsed", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_USER"));
}
@Override
public void mapUserToContext(UserDetails userDetails, DirContextAdapter dirContextAdapter) {
}
}
如何从Active Directory获取正确的SID?
答案 0 :(得分:1)
我认为答案就在这里:http://forum.spring.io/forum/spring-projects/data/ldap/66894-objectsid-and-ldaptemplate
在第二篇文章中,他描述了您遇到的同一问题。在上一篇文章中,他描述了一个修复,即将其添加到Bean配置文件中:
<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://ldapserver.domain.com:389" />
<property name="base" value="dc=domain,dc=com" />
<property name="userDn" value="cn=binduser,cn=Users,dc=domain,dc=com" />
<property name="password" value="bindpwd"/>
<property name="baseEnvironmentProperties">
<map>
<entry key="java.naming.ldap.attributes.binary">
<value>objectSid</value>
</entry>
</map>
</property>
</bean>
您必须修改域名的值,但我认为重要的部分是baseEnvironmentProperties
。
This thread还介绍了一种设置该方法的程序化方法(尽管对于objectGuid
,但您只需交换属性)。
AbstractContextSource contextSource = (AbstractContextSource) ldapTemplate.getContextSource();
Map<String,String> baseEnvironmentProperties = new HashMap<String, String>();
baseEnvironmentProperties.put("java.naming.ldap.attributes.binary", "objectSid");
contextSource.setBaseEnvironmentProperties(baseEnvironmentProperties);
contextSource.afterPropertiesSet();
答案 1 :(得分:0)
我通过在configure方法中添加环境属性来使其工作:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
private ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider =
new ActiveDirectoryLdapAuthenticationProvider(LdapConfig.AD_DOMAIN, LdapConfig.AD_SERVER);
// ************** NEW ENVIRONMENT PROPERTIES **********************************
Map<String, Object> environmentProperties = new HashMap<>();
environmentProperties.put("java.naming.ldap.attributes.binary", "objectsid");
provider.setContextEnvironmentProperties(environmentProperties);
// ************** END OF NEW ENVIRONMENT PROPERTIES ***************************
provider.setUserDetailsContextMapper(new LdapUserDetailsContextMapper());
return provider;
}
}
然后在UserDetailContextMapper中像这样读取它:
public class CustomUserDetailsContextMapper implements UserDetailsContextMapper {
private final static Logger logger = LoggerFactory.getLogger(CustomUserDetailsContextMapper.class);
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
logger.info(ctx.getDn().toString());
byte[] byteSid = null;
try {
byteSid = (byte[]) ctx.getAttributes().get("objectsid").get();
} catch (NamingException e) {
e.printStackTrace();
}
String sid = LdapUtils.convertBinarySidToString(byteSid);
logger.info("SID: {}", sid);
return new User(username, "notUsed", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_USER"));
}
我希望这会有所帮助!