简体   繁体   English

Spring Security 3 Active Directory身份验证,数据库授权

[英]Spring Security 3 Active Directory Authentication, Database Authorization

I'm trying to acces my application with AD authentication and getting authorization roles from my DB. 我正在尝试通过AD身份验证来访问我的应用程序,并从数据库中获取授权角色。

this is my configuration 这是我的配置

<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>

I tried to add 我试图添加

  <beans:constructor-arg>
    <beans:bean class="org.springframework.security.ldap.populator.UserDetailsServiceLdapAuthoritiesPopulator">
      <beans:constructor-arg ref="myUserDetailsService"/>
    </beans:bean>
  </beans:constructor-arg>

but it didn't work. 但这没用。 Any help? 有什么帮助吗?

Many thanks!! 非常感谢!!

ActiveDirectoryLdapAuthenticationProvider doesn't use an LdapAuthoritiesPopulator (check the API for the constructor). ActiveDirectoryLdapAuthenticationProvider不使用LdapAuthoritiesPopulator (检查API的构造函数)。

You can use a delegation model, where you wrap the provider and load the authorities separately, before returning a new token containing them: 您可以使用委派模型,在该模型中,您包装提供程序并分别加载权限,然后返回包含它们的新令牌:

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);
    }
}

The class is final mainly due to my rather basic knowledge of Active Directory and the different ways people would want to use it. 该课程是最终的,主要是由于我对Active Directory的基本知识以及人们希望使用它的不同方式。

Lets break this up into 2 parts. 让我们分成两部分。 First one would be your spring security xml configuration and the second part would be overriding the UserContextMapper that spring security provides. 第一个是您的Spring Security xml配置,第二个部分将覆盖Spring Security提供的UserContextMapper。

Your security xml configuration would be 您的安全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" />

The MyDbAuthorizationFetcher is the class where you would be implementing UserContextMapper class to fetch authorities from DB MyDbAuthorizationFetcher是您将在其中实现UserContextMapper类以从数据库获取授权的类。

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
}

}

需要在AbstractAuthenticationToken中将authenticated标志设置为true,除非未将其视为成功

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM