我正在尝试构建一个具有一些基本功能的@Restcontroller
,并使用ldap后端通过spring security 4进行身份验证/授权,所有这些都在java配置中。我有一些问题:
userDetailService
实现? 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);