spring security 4 RestController with ldap provider

时间:2015-12-18 07:51:42

标签: java spring security authentication ldap

我正在尝试构建一个具有一些基本功能的@Restcontroller,并使用ldap后端通过spring security 4进行身份验证/授权,所有这些都在java配置中。我有一些问题:

  • 在ldap中存储密码是真实世界场景,还是它们应该在数据库中的某个位置,并且涉及使用dao函数的自定义userDetailService实现?
  • 如果密码应存储在ldap中,那么PasswordComparisonAuthenticator是性能优化的方式(速度,与ldap的连续连接)?
  • 调用@RestController时,调用者应该如何进行身份验证以及需要在那里进行哪些java配置?

我当前的实现使用针对@RestController的简单httpBasic身份验证,但是当将authenticationProvider更改为ldap时,我遇到了一些错误(我看到错误的凭据错误,但我不知道为什么我会得到它),我错过了一些概念性的东西吗?:

Basic Authentication Authorization header found for user 'jfryer'
[DEBUG] [http-bio-8080-exec-3 04:06:02] (ProviderManager.java:authenticate:162) Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
[DEBUG] [http-bio-8080-exec-3 04:06:02] (AbstractLdapAuthenticationProvider.java:authenticate:67) Processing authentication request for user: jfryer
[DEBUG] [http-bio-8080-exec-3 04:06:02] (BasicAuthenticationFilter.java:doFilterInternal:196) Authentication request for failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
[DEBUG] [http-bio-8080-exec-3 04:06:02] (DelegatingAuthenticationEntryPoint.java:commence:78) Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
[DEBUG] [http-bio-8080-exec-3 04:06:02] (DelegatingAuthenticationEntryPoint.java:commence:91) No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint@56f05ca6
[DEBUG] [http-bio-8080-exec-3 04:06:02] (SecurityContextPersistenceFilter.java:doFilter:105) SecurityContextHolder now cleared, as request processing completed

java配置:

@Configuration
@EnableWebSecurity
@ComponentScan("my packages")
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public DefaultSpringSecurityContextSource contextSource() {
        DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://localhost:11389/o=sevenSeas");
        contextSource.setUserDn("uid=admin,ou=system");
        contextSource.setPassword("admin");
        return contextSource;
    }

    @Bean
    public PasswordComparisonAuthenticator ldapAuthenticator(DefaultSpringSecurityContextSource contextSource) {
        PasswordComparisonAuthenticator authenticator = new PasswordComparisonAuthenticator(contextSource);
        String[] userDn = {"cn={0},ou=people"}; 
        authenticator.setUserDnPatterns(userDn);
        authenticator.setPasswordAttributeName("userPassword");
        authenticator.setPasswordEncoder(new LdapShaPasswordEncoder());
        return authenticator;
    }

    @Bean
    public DefaultLdapAuthoritiesPopulator authoritiesPopulator(DefaultSpringSecurityContextSource contextSource) {
        DefaultLdapAuthoritiesPopulator populator = new DefaultLdapAuthoritiesPopulator(contextSource, "ou=groups");
        populator.setGroupRoleAttribute("cn");
        return populator;
    }

    @Bean
    public LdapAuthenticationProvider ldapAuthenticationProvider(DefaultSpringSecurityContextSource contextSource) {
        return new LdapAuthenticationProvider(this.ldapAuthenticator(contextSource), authoritiesPopulator(contextSource));
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth, DefaultSpringSecurityContextSource contextSource) throws Exception {
        //auth.userDetailsService(userDetailsService);
        auth.authenticationProvider(ldapAuthenticationProvider(contextSource));
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests().antMatchers("/hello/**").hasRole("ADMIN").antMatchers("/date/**").hasRole("USER").and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf().disable().exceptionHandling()
                .authenticationEntryPoint(new AuthenticationHandler()).accessDeniedHandler(new PermissionHandler());
    }
}

主叫代码:

    final String helloUri = "http://localhost:8080/Security/hello/Zoltan";
        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

        String auth = "jfryer:alma";
        byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));
        String authHeader = "Basic " + new String(encodedAuth);
        headers.add("Authorization", authHeader);

        HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);

        ResponseEntity<String> result = restTemplate.exchange(helloUri, HttpMethod.POST, entity, String.class);

0 个答案:

没有答案