将身份验证提供程序添加到Spring Security Java配置

时间:2016-10-24 07:27:51

标签: java spring spring-security spring-java-config xml-configuration

我在XML配置中的代码:

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>

工作正常,但我无法转换为Java代码。

错误:

java.lang.NullPointerException
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:164)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)

WebSecurityConfiguration

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    // @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .authenticationProvider(customAuthenticationProvider); // .build()
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
                .ignoring()
                .antMatchers("/resources/**")
                .antMatchers("/assets/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        //      .authenticationProvider(customAuthenticationProvider)
                .authorizeRequests()
                    .antMatchers("/login","/logout").permitAll().antMatchers("/admin/**", "/admin*").hasRole("ADMIN").antMatchers("/**").hasRole("USER")
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .usernameParameter("username").passwordParameter("password")
                    .defaultSuccessUrl("/")
                    .permitAll()
                    .and()
                    .exceptionHandling().accessDeniedPage("/Access_Denied")
                    .and()
                .logout()
                    .permitAll();

        http.csrf().disable();
    }

    // @Bean
    // DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() {
    //     return new DefaultWebSecurityExpressionHandler();
    // }
}

CustomAuthenticationProvider

// @Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
    private final CustomUserDetailsService userDetailsService;

    @Autowired
    public CustomAuthenticationProvider(CustomUserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName().toLowerCase();
        String password = (String) authentication.getCredentials();

        userDetailsService.setPassword(password);
        User user = userDetailsService.loadUserByUsername(username);

        if (user == null) {
             throw new BadCredentialsException("Username not found.");
        }

        if (!password.equals(user.getPassword())) {
             throw new BadCredentialsException("Wrong password.");
        }

        userDetailsService.setAuthorized(username);

        Collection<?extends GrantedAuthority> authorities = user.getAuthorities();

        return new UsernamePasswordAuthenticationToken(user, password, authorities);
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}

2 个答案:

答案 0 :(得分:0)

我也有同样的例外。 如果未通过任何身份验证提供程序,则会得到此异常。

如果您不提供身份验证提供程序 如果您传递空值

1。
您可能错过了注入authenticationProvider依赖项
.authenticationProvider(customAuthenticationProvider)

评论行
//.authenticationProvider(customAuthenticationProvider)
还是
您可能错过了@Component for CustomAuthenticationProvider
OP犯了同样的错误。

  1. 在我的情况下缺少@Autowired
    (我既配置了授权,也配置了身份验证,但通过了null)
//Missed autowired annotation
private CustomAuthenticationProvider customAuthenticationProvider;

并尝试注入null

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception 
  {
      auth.authenticationProvider(customAuthenticationProvider); // Null passed here
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests()
          .antMatchers("/**").hasRole("ADMIN")
          .anyRequest()
          .authenticated()
          .and()
          .formLogin();
  }

对于您来说,上述代码块等效于

@Override
  protected void configure(HttpSecurity http) throws Exception {
      http.authorizeRequests()
          .antMatchers("/**").hasRole("ADMIN")
          .anyRequest()
          .authenticated()
          .and()
          .formLogin()
          .authenticationProvider(customAuthenticationProvider);
  }

答案 1 :(得分:-1)

如果您使用的是弹簧靴,则可以

@configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

 @Override
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customAuthenticationProvider());
    }

//customAuthenticationProvider() method creates your bean

}

//添加有问题的代码后编辑

好的,问题不在于auth提供程序的设置,而在于您自己的代码。 NPE显示您的自定义实现中未初始化某些内容。提供的自动装配是否正确,是否有所有deps? 见What is a NullPointerException, and how do I fix it?