Spring Security 3 Active Directory 身份验证、数据库授权
Posted
技术标签:
【中文标题】Spring Security 3 Active Directory 身份验证、数据库授权【英文标题】:Spring Security 3 Active Directory Authentication, Database Authorization 【发布时间】:2012-03-02 23:46:01 【问题描述】:我正在尝试使用 AD 身份验证访问我的应用程序并从我的数据库中获取授权角色。
这是我的配置
<beans:bean id="activeDirectoryAuthenticationProvider"
class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<beans:constructor-arg value="mydomain" />
<beans:constructor-arg value="ldap://my URL :389" />
<beans:property name="convertSubErrorCodesToExceptions" value="true"/>
</beans:bean>
我尝试添加
<beans:constructor-arg>
<beans:bean class="org.springframework.security.ldap.populator.UserDetailsServiceLdapAuthoritiesPopulator">
<beans:constructor-arg ref="myUserDetailsService"/>
</beans:bean>
</beans:constructor-arg>
但它没有用。有什么帮助吗?
非常感谢!!
【问题讨论】:
【参考方案1】:ActiveDirectoryLdapAuthenticationProvider 不使用LdapAuthoritiesPopulator
(检查构造函数的 API)。
您可以使用委托模型,在其中包装提供者并分别加载权限,然后返回包含它们的新令牌:
public class MyAuthoritySupplementingProvider implements AuthenticationProvider
private AuthenticationProvider delegate;
public MyAuthoritySupplementingProvider(AuthenticationProvider delegate)
this.delegate = delegate;
public Authentication authenticate(Authentication authentication)
final Authentication a = delegate.authenticate(authentication);
// Load additional authorities and create an Authentication object
final List<GrantedAuthority> authorities = loadRolesFromDatabaseHere(a.getName());
return new AbstractAuthenticationToken(authorities)
public Object getCredentials()
throw new UnsupportedOperationException();
public Object getPrincipal()
return a.getPrincipal();
;
@Override
public boolean supports(Class<?> authentication)
return delegate.supports(authentication);
这门课是期末课,主要是因为我对 Active Directory 的基本了解以及人们想要使用它的不同方式。
【讨论】:
非常感谢。我该怎么做?我对这种技术很陌生,我找不到任何使用 ActiveDirectoryLdapAuthenticationProvider 和自定义 loadUserAuthorities 的示例 只需扩展类,调用您的数据库以获取角色并根据方法签名将它们作为List<GrantedAuthority>
返回。您可以使用SimpleGrantedAuthority
类来包装各个角色。
我试图扩展它,但我得到了错误:不能继承最终类 ActiveDirectoryLdapAuthenticationProvider
糟糕,抱歉。我忘记了。您必须使用委托而不是继承。我已经修改了我的答案以建议如何完成。【参考方案2】:
让我们把它分成两部分。第一个是您的 spring security xml 配置,第二部分是覆盖 spring security 提供的 UserContextMapper。
您的安全 xml 配置将是
<bean id="adAuthenticationProvider"
class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<constructor-arg value="my.domain.com" />
<constructor-arg value="ldap://<adhostserver>:<port>/" />
<property name="convertSubErrorCodesToExceptions" value="true" />
<property name="userDetailsContextMapper" ref="myUserDetailsContextMapper" />
</bean>
<bean id="myUserDetailsContextMapper" class="com.mycompany.sme.workflow.controller.MyDbAuthorizationFetcher">
<property name="dataSource" ref="dataSource" />
MyDbAuthorizationFetcher 是您将在其中实现 UserContextMapper 类以从 DB 获取权限的类
public class MyDbAuthorizationFetcher implements UserDetailsContextMapper
private JdbcTemplate jdbcTemplate;
@Autowired
private DataSource dataSource;
public JdbcTemplate getJdbcTemplate()
return jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate)
this.jdbcTemplate = jdbcTemplate;
public DataSource getDataSource()
return dataSource;
public void setDataSource(DataSource dataSource)
this.dataSource = dataSource;
// populating roles assigned to the user from AUTHORITIES table in DB
private List<SimpleGrantedAuthority> loadRolesFromDatabase(String username)
DbRole role = new DbRole();
String sql = "select * from user where user_id = ?";
jdbcTemplate = new JdbcTemplate(getDataSource());
role = jdbcTemplate.queryForObject(sql, new Object[] username , new DbRoleMapper());
try
dataSource.getConnection().setAutoCommit(true);
catch (SQLException e)
List<SimpleGrantedAuthority> authoritiess = new ArrayList<SimpleGrantedAuthority>();
SimpleGrantedAuthority auth = new SimpleGrantedAuthority(String.valueOf(role.getRoleId()));
authoritiess.add(auth);
return authoritiess;
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx,
String username, Collection<? extends GrantedAuthority> authorities)
List<SimpleGrantedAuthority> allAuthorities = new ArrayList<SimpleGrantedAuthority>();
for (GrantedAuthority auth : authorities)
if (auth != null && !auth.getAuthority().isEmpty())
allAuthorities.add((SimpleGrantedAuthority) auth);
// add additional roles from the database table
allAuthorities.addAll(loadRolesFromDatabase(username));
return new User(username, "", true, true, true, true, allAuthorities);
@Override
public void mapUserToContext(UserDetails user, DirContextAdapter ctx)
// TODO Auto-generated method stub
【讨论】:
我认为这是更简洁的解决方案,如果您需要,它还可以让您访问用户的 AD 属性。【参考方案3】:需要在AbstractAuthenticationToken中将authenticated flag设置为true,除非它不认为是成功
【讨论】:
以上是关于Spring Security 3 Active Directory 身份验证、数据库授权的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security 3 Active Directory 身份验证、数据库授权
通过 Active Directory LDAP 使用 Spring-Security 进行身份验证
Spring Security Active Directory 错误凭据处理(错误 49)
Spring Security Active Directory LDAP 身份验证错误
具有 Active Directory 和数据库角色的 Spring Security
Spring Security - 在Spring Boot中针对LDAP使用Active Directory对用户进行身份验证