【问题标题】:Java Spring Security - Application Role Based Active Directory User AuthenticationJava Spring Security - 基于应用程序角色的 Active Directory 用户身份验证
【发布时间】:2014-05-23 22:41:03
【问题描述】:

我正在使用 spring mvc 框架和 java 开发一个 web 应用程序。我在应用程序中使用 Active Directory 用户身份验证。

现在我想从 sql 数据库为这些用户分配角色。因此,整个身份验证过程将通过从两个来源获取信息来完成:[来自活动目录的用户 ID 和密码以及来自 sql 数据库的用户角色]。

我在互联网上搜索了任何教程/示例,但我无法获得任何有用的东西。因此,我们将不胜感激有关此问题的任何帮助。

这是我的 spring 安全文件的当前代码,

<bean id="adAuthenticationProvider"
      class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
    <constructor-arg value="abbl.org"/>
    <constructor-arg value="LDAP://abbl.org"/>
    <property name="convertSubErrorCodesToExceptions" value="true"/>
    <property name="useAuthenticationRequestCredentials" value="true"/>
</bean>

<bean id="customAuthenticationProvider"
      class="org.abbl.exhbp.templates.CustomAuthorityProvider">
    <constructor-arg ref="adAuthenticationProvider"/>
</bean>

<security:authentication-manager>
    <security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>

我在 AuthenticationProvider 类中的身份验证函数,

public Authentication authenticate(Authentication authentication) {

    final Authentication a = delegate.authenticate(authentication);

    // Load additional authorities and create an Authentication object
    final List<GrantedAuthority> authorities = getGrantedAuthorities(a.getName());

    return new AbstractAuthenticationToken(authorities) {
        @Override
        public Object getCredentials() {
            //return null;  //To change body of implemented methods use File | Settings | File Templates.
            throw new UnsupportedOperationException();
        }

        @Override
        public Object getPrincipal() {
            //return null; //To change body of implemented methods use File | Settings | File Templates.
            return a.getPrincipal();
        }
    };
}

登录后,我得到了这个异常,

java.lang.UnsupportedOperationException
org.abbl.exhbp.templates.CustomAuthorityProvider$1.getCredentials(CustomAuthorityProvider.java:41)
org.springframework.security.authentication.AbstractAuthenticationToken.eraseCredentials(AbstractAuthenticationToken.java:108)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:186)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:195)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)

我需要在这里做哪些修改或实现才能实现我上面提到的?

【问题讨论】:

  • 看看this answer
  • 当您发表评论时,我只是在看那个答案。实际上我是 Spring 框架的新手。到目前为止,从互联网上寻找参考和样本。因此,如果您可以向我提供任何示例项目或指导方针,我将如何实现我想要做的事情,这将对我非常有帮助。我非常了解您的自定义 AuthenticationProvider 类。我没有得到确切的信息,它将如何与我的 sql 数据库进行通信,以及数据库将以何种格式跟踪用户及其角色。期待您能在这方面帮助我...
  • 您可以以任何您想要的方式存储用户/角色。例如,该链接中的函数loadRolesFromDatabaseHere 只会根据用户的姓名加载该用户的角色。您将自己编写 SQL。类似于this FAQ 的代码就可以了。
  • @Luke Taylor:我根据建议和参考做了必要的修改。但是登录后,我得到了avobe异常。你能准确地告诉我我在这里做错了什么吗? :-/

标签: java database spring-security active-directory roles


【解决方案1】:

最后我通过使用 UsernamePasswordAuthenticationToken 而不是 AbstractAuthenticationToken 实现了我的目标。解决方法如下,

1) spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:security="http://www.springframework.org/schema/security"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/security
   http://www.springframework.org/schema/security/spring-security.xsd">


<security:http auto-config="true" use-expressions="true">
    <security:anonymous enabled="false"/>
    <security:form-login login-page="/login" default-target-url="/home"
                         login-processing-url="/j_spring_security_check"
                         authentication-failure-url="/loginfailed"/>
    <security:logout logout-success-url="/logout"/>
</security:http>

<bean id="adAuthenticationProvider"
      class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
    <constructor-arg value="DOMAIN"/>
    <constructor-arg value="URL"/>
    <property name="convertSubErrorCodesToExceptions" value="true"/>
    <property name="useAuthenticationRequestCredentials" value="true"/>
</bean>

<bean id="customAuthenticationProvider"
      class="org.abbl.exhbp.templates.CustomAuthorityProvider">
    <constructor-arg ref="adAuthenticationProvider"/>
</bean>

<security:authentication-manager>
    <security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>

2) CustomAuthorityProvider.class

public class CustomAuthorityProvider implements AuthenticationProvider {

private AuthenticationProvider delegate;

public CustomAuthorityProvider(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 = getGrantedAuthorities(a.getName());

    return new UsernamePasswordAuthenticationToken(a.getPrincipal(),a.getCredentials(),authorities);
}

@Override
public boolean supports(Class<?> authentication) {
    return delegate.supports(authentication);
}

List<GrantedAuthority> getGrantedAuthorities(String username) {
    JdbcTemplateDataSource ds = new JdbcTemplateDataSource();
    List<GrantedAuthority> roles = ds.getJdbcTemplate().query("select r.Role from Users u join UserRole ur on u.UserId = "
            + "ur.UserId join Roles r on r.RoleId = ur.RoleId where Username = ?",
            new String[]{username},
            new RowMapper<GrantedAuthority>() {
                public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
                    return new SimpleGrantedAuthority(rs.getString(1));
                }
            });
    return roles;
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 2020-04-08
    • 2021-12-09
    • 2021-03-31
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    相关资源
    最近更新 更多