2012-02-10 2 views
2

Я пытаюсь получить мое приложение с аутентификацией AD и получением ролей авторизации из моей БД.Spring Security 3 Аутентификация Active Directory, авторизация базы данных

это моя конфигурация

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

, но это не сработало. Любая помощь?

Большое спасибо!

ответ

3

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

Класс является окончательным, главным образом, из-за мои достаточно базовые знания Активного Справочник и разные способы, которыми люди захотят его использовать.

+0

Спасибо большое. Как мне это сделать? Я довольно новичок в этой технике, и я не смог найти какой-либо пример, который использует ActiveDirectoryLdapAuthenticationProvider с пользовательскими loadUserAuthorities. –

+0

Просто расширьте класс, позвоните в свою базу данных, чтобы получить роли, и верните их как «Список » в соответствии с методом подпись. Вы можете использовать класс SimpleGrantedAuthority для обертывания отдельных ролей. –

+0

Я пытался расширить его, но я получаю ошибку: не могу подклассифицировать последний класс ActiveDirectoryLdapAuthenticationProvider –

0

нужно установить флаг аутентификацией, как истинный в AbstractAuthenticationToken, если его не воспринимаю это как успех

1

Позволяет разорвать этот вверх в 2-х частей. Прежде всего, это будет ваша конфигурация xml безопасности весны, а вторая часть будет переопределять 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 класс, чтобы принести власти из БД

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 
} 

} 
+0

Я думаю, что это более чистое решение, и оно дает вам доступ к свойствам AD для пользователя, если они вам понадобятся. – Doughnuts