java-Spring Security getAuthenticationManager()在自定义过滤器中返回null
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-Spring Security getAuthenticationManager()在自定义过滤器中返回null,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5300字,纯文字阅读大概需要8分钟。
内容图文
![java-Spring Security getAuthenticationManager()在自定义过滤器中返回null](/upload/InfoBanner/zyjiaocheng/669/0ff11dd417d24d2aa13a843ea94ba669.jpg)
我试图在Spring中实现一个非常简单的自定义身份验证过程示例,以更好地理解该概念.
我以为我现在已经准备好了一切,但是发送了一个请求以测试我实现了什么,结果导致NullPointerException可以追溯到
this.getAuthenticationManager()在我的自定义过滤器中返回null.但是我不明白为什么.不幸的是,现有的非常相似的问题并没有真正帮助我.因此,我将感谢您的帮助;这是我认为最相关的课程,请随时询问是否需要更多课程.
MyAuthenticationFilter(基于UsernamePasswordAuthenticationFilter的源代码),此行的最后一行发生错误:
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;
}
}
MyAuthenticationProvider:
@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);
}
}
解决方法:
为什么看到NullPointerException
您看到的是NullPointerException,因为您没有将AuthenticationManager连接到过滤器中.根据javadocs的AbstractAuthenticationProcessingFilter
The filter requires that you set the authenticationManager property. An AuthenticationManager is required to process the authentication request tokens created by implementing classes
在这种情况下,我确实对为什么authenticationManager没有对抽象过滤器的构造函数参数进行简化的问题scratch之以鼻.我建议在您的自定义过滤器的构造函数中强制执行此操作.
public MyAuthenticationFilter(AuthenticationManager authenticationManager) {
super(new AntPathRequestMatcher("/login", "POST"));
this.setAuthenticationManager(authenticationManager);
}
AuthenticationManager或AuthenticationProvider
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(myAuthenticationProvider);
}
AuthenticationManagerBuilder将创建一个ProviderManager(一个AuthenticationManager).
ProviderManager是AuthenticationProvider的集合,并将尝试与它管理的每个AuthenticationProvider进行authenticate(). (这是public boolean支持(Class<?>身份验证)在AuthenticationProvider合同中非常重要的地方)
在您的配置中,您已经创建了一个ProviderManager,其中仅包含您的自定义身份验证提供程序
凉.现在我的AuthenticationManager在哪里?
可以通过WebSecurityConfigurerAdapter中的this.authenticationManager()来获取由configure()方法构建的AuthenticationManager.
@Bean
public AuthenticationManager authenticationManager throws Exception() {
this.authenticationManager();
}
推荐建议
创建自己的ProviderManager确实有其好处,因为它是显式的并且在您的控制之内.
@Bean
public AuthenticationManager authenticationManager() {
return new ProviderManager(Arrays.asList(myAuthenticationProvider));
}
这将使您灵活地放置AuthenticationManager bean,并避免:
>您的bean配置中潜在的循环依赖问题
>通过调用this.authenticationManager()使检查的异常冒泡
全部放在一起
...
public class AppConfig extends WebSecurityConfigurerAdapter {
@Autowired
MyAuthenticationProvider myAuthenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new MyAuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class)
...
}
@Bean
public AuthenticationManager authenticationManager() {
return new ProviderManager(Arrays.asList(myAuthenticationProvider));
}
}
内容总结
以上是互联网集市为您收集整理的java-Spring Security getAuthenticationManager()在自定义过滤器中返回null全部内容,希望文章能够帮你解决java-Spring Security getAuthenticationManager()在自定义过滤器中返回null所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。