Spring 安全 LDAP 身份验证用户必须是 AD 组的成员
Spring Security LDAP authentication user must be a member of an AD group
我已经按照以下方式配置了 Spring 启动安全:
https://spring.io/guides/gs/securing-web/
我可以完美地使用我的凭据登录。但是,我需要添加一个检查,确保 AD 用户也必须属于特定的 AD 组(即 AD-this-is-a-specific-group). 登录时,如果用户不属于特定的AD组,那么应该return登录错误。
我已经搜索了几个小时,似乎无法在 WebSecurityConfigurerAdapter
中找到明确的方法,我是否正确使用了 auth.groupSearchFilter
?
这是我的代码:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
Environment env;
public LdapContextSource contextSource () {
LdapContextSource contextSource= new LdapContextSource();
contextSource.setUrl(env.getRequiredProperty("ldap.url"));
contextSource.setBase(env.getRequiredProperty("ldap.baseDn"));
contextSource.setUserDn(env.getRequiredProperty("ldap.bindDn"));
contextSource.setPassword(env.getRequiredProperty("ldap.batchPassword"));
contextSource.afterPropertiesSet();
return contextSource;
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.ldapAuthentication()
.userSearchFilter("(cn={0})")
.groupSearchBase("OU=Account Groups,OU=ITS Security")
.groupSearchFilter("(cn=AD-this-is-a-specific-group)")
.contextSource(contextSource());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
不确定这是否是最好的方法(就 Spring 安全生命周期 而言),但基本上我提供了我自己的 DefaultLdapAuthoritiesPopulator
,我只覆盖 getGroupMembershipRoles
.
首先,上面的auth.groupSearchFilter
我错了,应该是:
.groupSearchFilter("(member={0})")
其次,我创建了一个匿名 class 并使用了重写方法(它调用 super 并检查角色列表中的成员资格):
auth
.ldapAuthentication()
.ldapAuthoritiesPopulator(new DefaultLdapAuthoritiesPopulator(contextSource, "OU=Account Groups,OU=ITS Security") {
@Override
public Set<GrantedAuthority> getGroupMembershipRoles(String userDn, String username) {
Set<GrantedAuthority> groupMembershipRoles = super.getGroupMembershipRoles(userDn, username);
boolean isMemberOfSpecificAdGroup = false;
for (GrantedAuthority grantedAuthority : groupMembershipRoles) {
if ("ROLE_AD-this-is-a-specific-group".equals(grantedAuthority.toString())) {
isMemberOfSpecificAdGroup = true;
break;
}
}
if (!isMemberOfSpecificAdGroup ) {
throw new BadCredentialsException("User must be a member of " + "AD-this-is-a-specific-group");
}
return groupMembershipRoles;
}
})
.userSearchFilter("(cn={0})")
.groupSearchBase("OU=Account Groups,OU=ITS Security")
.groupSearchFilter("(member={0})")
.contextSource(contextSource);
很抱歉我迟到了 5 年,但我在 Spring Boot 中实现的非常简单的 LDAP 身份验证遇到了完全相同的问题。
我只想要这个:
- 用户名正确吗?
- 密码正确吗?
- 如果是,usr 是否在组 MYGROUP 中?
所以我的配置方法现在看起来真的很小。我在一个单独的 bean 中添加了 populator,只是意识到我需要将它添加到 "auth.ldapAuthentication" 中以便调用它。
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userSearchFilter("uid={0}")
.ldapAuthoritiesPopulator(ldapAuthoritiesPopulator())
.groupSearchFilter("(member={0})")
.contextSource(contextSource());
}
@Bean
public LdapAuthoritiesPopulator ldapAuthoritiesPopulator() {
DefaultLdapAuthoritiesPopulator populi = new DefaultLdapAuthoritiesPopulator(contextSource(), "") {
@Override
public Set<GrantedAuthority> getGroupMembershipRoles(String userDn, String username) {
Set<GrantedAuthority> groupMembershipRoles = super.getGroupMembershipRoles(userDn, username);
boolean isMemberOfSpecificAdGroup = false;
for (GrantedAuthority grantedAuthority : groupMembershipRoles) {
if ("ROLE_MYGROUP".equals(grantedAuthority.toString())) {
isMemberOfSpecificAdGroup = true;
break;
}
}
if (!isMemberOfSpecificAdGroup) {
throw new BadCredentialsException("User must be a member of " + "ROLE_MYGROUP");
}
return groupMembershipRoles;
}
};
return populi;
}
@Bean
public DefaultSpringSecurityContextSource contextSource() {
return new DefaultSpringSecurityContextSource("ldap://blabla-some-url:389/dc=something,dc=something,dc=ch");
}
顺便说一下:url 没有像 Spring Boot guide 中提到的那样工作,它只像这样工作,就像一行中的所有内容一样:
return new DefaultSpringSecurityContextSource("ldap://blabla-some-url:389/dc=something,dc=something,dc=ch");
顺便说一句,对于遵循该指南的每个人:如果您连接到一个已经存在的 LDAP 服务器,则不需要所有这些 "spring.ldap.embedded" 应用程序属性。
非常感谢您的帮助!
我会把它放在这里,因为我认为这是无需覆盖任何方法的更简单的方法。
如果符合您的 LDAP 结构,请在用户搜索过滤器(我将使用您的)中添加以下内容
原文:
.userSearchFilter("(cn={0})")
修改为搜索角色:
.userSearchFilter("(&(cn={0})(memberOf=CN=MYGROUP,OU=GROUP,DC=com,DC=company)")
这会同时搜索用户和会员资格
就我而言,我必须这样做,因为我有 3 个可能的角色:
(&(cn={0})(|(group1)(group2)(group3)))
如您所见,它会搜索用户和 1 个或多个角色
感谢此问题的答案:Spring Security Ldap, log in only users in specified group
我已经按照以下方式配置了 Spring 启动安全: https://spring.io/guides/gs/securing-web/
我可以完美地使用我的凭据登录。但是,我需要添加一个检查,确保 AD 用户也必须属于特定的 AD 组(即 AD-this-is-a-specific-group). 登录时,如果用户不属于特定的AD组,那么应该return登录错误。
我已经搜索了几个小时,似乎无法在 WebSecurityConfigurerAdapter
中找到明确的方法,我是否正确使用了 auth.groupSearchFilter
?
这是我的代码:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
Environment env;
public LdapContextSource contextSource () {
LdapContextSource contextSource= new LdapContextSource();
contextSource.setUrl(env.getRequiredProperty("ldap.url"));
contextSource.setBase(env.getRequiredProperty("ldap.baseDn"));
contextSource.setUserDn(env.getRequiredProperty("ldap.bindDn"));
contextSource.setPassword(env.getRequiredProperty("ldap.batchPassword"));
contextSource.afterPropertiesSet();
return contextSource;
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.ldapAuthentication()
.userSearchFilter("(cn={0})")
.groupSearchBase("OU=Account Groups,OU=ITS Security")
.groupSearchFilter("(cn=AD-this-is-a-specific-group)")
.contextSource(contextSource());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
不确定这是否是最好的方法(就 Spring 安全生命周期 而言),但基本上我提供了我自己的 DefaultLdapAuthoritiesPopulator
,我只覆盖 getGroupMembershipRoles
.
首先,上面的auth.groupSearchFilter
我错了,应该是:
.groupSearchFilter("(member={0})")
其次,我创建了一个匿名 class 并使用了重写方法(它调用 super 并检查角色列表中的成员资格):
auth
.ldapAuthentication()
.ldapAuthoritiesPopulator(new DefaultLdapAuthoritiesPopulator(contextSource, "OU=Account Groups,OU=ITS Security") {
@Override
public Set<GrantedAuthority> getGroupMembershipRoles(String userDn, String username) {
Set<GrantedAuthority> groupMembershipRoles = super.getGroupMembershipRoles(userDn, username);
boolean isMemberOfSpecificAdGroup = false;
for (GrantedAuthority grantedAuthority : groupMembershipRoles) {
if ("ROLE_AD-this-is-a-specific-group".equals(grantedAuthority.toString())) {
isMemberOfSpecificAdGroup = true;
break;
}
}
if (!isMemberOfSpecificAdGroup ) {
throw new BadCredentialsException("User must be a member of " + "AD-this-is-a-specific-group");
}
return groupMembershipRoles;
}
})
.userSearchFilter("(cn={0})")
.groupSearchBase("OU=Account Groups,OU=ITS Security")
.groupSearchFilter("(member={0})")
.contextSource(contextSource);
很抱歉我迟到了 5 年,但我在 Spring Boot 中实现的非常简单的 LDAP 身份验证遇到了完全相同的问题。
我只想要这个: - 用户名正确吗? - 密码正确吗? - 如果是,usr 是否在组 MYGROUP 中?
所以我的配置方法现在看起来真的很小。我在一个单独的 bean 中添加了 populator,只是意识到我需要将它添加到 "auth.ldapAuthentication" 中以便调用它。
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userSearchFilter("uid={0}")
.ldapAuthoritiesPopulator(ldapAuthoritiesPopulator())
.groupSearchFilter("(member={0})")
.contextSource(contextSource());
}
@Bean
public LdapAuthoritiesPopulator ldapAuthoritiesPopulator() {
DefaultLdapAuthoritiesPopulator populi = new DefaultLdapAuthoritiesPopulator(contextSource(), "") {
@Override
public Set<GrantedAuthority> getGroupMembershipRoles(String userDn, String username) {
Set<GrantedAuthority> groupMembershipRoles = super.getGroupMembershipRoles(userDn, username);
boolean isMemberOfSpecificAdGroup = false;
for (GrantedAuthority grantedAuthority : groupMembershipRoles) {
if ("ROLE_MYGROUP".equals(grantedAuthority.toString())) {
isMemberOfSpecificAdGroup = true;
break;
}
}
if (!isMemberOfSpecificAdGroup) {
throw new BadCredentialsException("User must be a member of " + "ROLE_MYGROUP");
}
return groupMembershipRoles;
}
};
return populi;
}
@Bean
public DefaultSpringSecurityContextSource contextSource() {
return new DefaultSpringSecurityContextSource("ldap://blabla-some-url:389/dc=something,dc=something,dc=ch");
}
顺便说一下:url 没有像 Spring Boot guide 中提到的那样工作,它只像这样工作,就像一行中的所有内容一样:
return new DefaultSpringSecurityContextSource("ldap://blabla-some-url:389/dc=something,dc=something,dc=ch");
顺便说一句,对于遵循该指南的每个人:如果您连接到一个已经存在的 LDAP 服务器,则不需要所有这些 "spring.ldap.embedded" 应用程序属性。
非常感谢您的帮助!
我会把它放在这里,因为我认为这是无需覆盖任何方法的更简单的方法。
如果符合您的 LDAP 结构,请在用户搜索过滤器(我将使用您的)中添加以下内容
原文:
.userSearchFilter("(cn={0})")
修改为搜索角色:
.userSearchFilter("(&(cn={0})(memberOf=CN=MYGROUP,OU=GROUP,DC=com,DC=company)")
这会同时搜索用户和会员资格
就我而言,我必须这样做,因为我有 3 个可能的角色:
(&(cn={0})(|(group1)(group2)(group3)))
如您所见,它会搜索用户和 1 个或多个角色
感谢此问题的答案:Spring Security Ldap, log in only users in specified group