私は概念の理解を得るために、春にカスタマイズされた認証プロセスの非常に簡単な例を実装しようとしています。
私は今の場所ですべてを持っていたと思ったが、私はまで追跡することができNullPointerExceptionがで結果を実装何のテストにリクエストを送信するthis.getAuthenticationManager()私のカスタムフィルタに戻っヌル。しかし、私はなぜ理解していません。非常によく似た既存の質問は本当に残念ながら、私を助けていませんでした。だから私は助けのために感謝するでしょう。ここでは、それ以上が必要な場合はお気軽に、私が考える最も関連性の高いクラスです。
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
自分のフィルターに配線します。Javadocによると、AbstractAuthenticationProcessingFilter
フィルタを使用すると、authenticationManagerプロパティを設定する必要があります。アンAuthenticationManagerは、クラスを実装することによって作成された認証リクエストトークンを処理するために必要とされます
そうすると、私は理由を私の頭に傷を付けないauthenticationManager
この抽象フィルタのコンストラクタの引数にカットをしませんでした。私は、カスタムフィルタのためのあなたのコンストラクタでこれを強制することをお勧めします。
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 (an AuthenticationManager)
。
ProviderManager
集合体であるAuthenticationProvider
としようとするauthenticate()
すべてのとAuthenticationProvider
、それが管理しています。(これはどこでpublic boolean supports(Class<?> authentication)
で非常に重要であるAuthenticationProvider
契約)
お使いの設定では、作成したProviderManager
含むちょうどあなたのカスタムをAuthentication Provider
涼しい。今、私のAuthenticationManagerはどこにありますか?
つかむことが可能であるAuthenticationManager
ことで構築されたconfigure()
方法をthis.authenticationManager()
中WebSecurityConfigurerAdapter
@Bean
public AuthenticationManager authenticationManager throws Exception() {
this.authenticationManager();
}
勧告
あなた自身を作成すると、ProviderManager
それが明示的にし、あなたのコントロール内にあるとして、それの利点を持っています。
@Bean
public AuthenticationManager authenticationManager() {
return new ProviderManager(Arrays.asList(myAuthenticationProvider));
}
これは、あなたの配置を柔軟にできるようになるAuthenticationManager
豆と回避:
- あなたの豆の構成では潜在的な循環依存の問題
- バブルアップチェックし
Exception
、呼び出しの結果として、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));
}
}