我试图在Spring中实现一个非常简单的自定义身份验证过程的示例,以便更好地理解这个概念。
我以为我现在已经准备好了一切,但是发送一个请求来测试我实现的东西,结果导致了一个NullPointerException,可以追溯到 this.getAuthenticationManager() 在我的自定义过滤器中返回null。但是我不明白为什么。很不幸,这个非常相似的现有问题并没有真正帮助我。所以我会感谢帮助;这里是我认为最相关的课程,如果还需要的话,请随时询问。
- MyAuthenticationFilter*(基于用户名密码AuthenticationFilter的源代码),错误发生在以下代码的最后一行:
public class MyAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public MyAuthenticationFilter() {
super(new AntPathRequestMatcher("/login", "POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
String username = request.getParameter("username");
String password = request.getParameter("password");
String secondSecret = request.getParameter("secondSecret");
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
MyAuthenticationToken authRequest = new MyAuthenticationToken(username, new MyCredentials(password, secondSecret));
return this.getAuthenticationManager().authenticate(authRequest);
}
}
我的配置类:
@Configuration
@EnableWebSecurity
@EnableWebMvc
@ComponentScan
public class AppConfig extends WebSecurityConfigurerAdapter {
@Autowired
MyAuthenticationProvider myAuthenticationProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(myAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new MyAuthenticationFilter(), BasicAuthenticationFilter.class)
.authorizeRequests().antMatchers("/**")
.hasAnyRole()
.anyRequest()
.authenticated()
.and()
.csrf().disable();
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
- 我的验证提供者 *:
@Component
public class MyAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
MyAuthenticationToken myAuthenticationToken = (MyAuthenticationToken) authentication;
MyCredentials credentials = (MyCredentials) myAuthenticationToken.getCredentials();
if (credentials.getPassword().equals("sesamOeffneDich") && credentials.getSecondSecret().equals(MyAuthenticationToken.SECOND_SECRET)) {
myAuthenticationToken.setAuthenticated(true);
return myAuthenticationToken;
} else {
throw new BadCredentialsException("Bad credentials supplied!");
}
}
@Override
public boolean supports(Class<?> authentication) {
return MyAuthenticationToken.class.isAssignableFrom(authentication);
}
}
3条答案
按热度按时间nfs0ujit1#
为什么会出现NullPointerException
您看到的是
NullPointerException
,因为您的过滤器中没有连接AuthenticationManager
。筛选器要求您设置authenticationManager属性。需要AuthenticationManager来处理通过实现类创建的身份验证请求令牌
在这种情况下,我确实想不通为什么
authenticationManager
没有为这个抽象过滤器的构造函数参数进行剪切。我建议在自定义过滤器的构造函数中强制执行这一点。验证管理器或验证提供程序
AuthenticationManagerBuilder
将创建一个ProviderManager (an AuthenticationManager)
。ProviderManager
是AuthenticationProvider
的集合,它将尝试对它管理的每个AuthenticationProvider
执行authenticate()
。(这是public boolean supports(Class<?> authentication)
在AuthenticationProvider
协定中极其重要的地方)在您的配置中,您已经创建了一个仅包含自定义
Authentication Provider
的ProviderManager
太棒了。现在我的验证管理器在哪里?
在
WebSecurityConfigurerAdapter
中,可以通过this.authenticationManager()
获取由configure()
方法生成的AuthenticationManager
。建议事项
创建您自己的
ProviderManager
确实有它的好处,因为它将是明确的,并在您的控制范围内。这将使您可以灵活地放置
AuthenticationManager
Bean,并避免:this.authenticationManager()
而使选中的Exception
冒泡将一切整合
ffx8fchx2#
您应该为过滤器设置身份验证管理器。
并使用修改configure方法
一个月一个月...
u3r8eeie3#
在我的情况下没有帮助除了这: