2016-05-10 24 views
3

この質問は実際にこの問題problemに関連しています。春のセキュリティ - カスタムExceptionTranslationFilter

@ harsh-poddarの提案に基づいて、私はそれに応じてフィルタを追加しました。

ただし、有効な資格情報でもログインできないようです。

次の関連コードである:

SecurityConfig

@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

// @Bean 
// public CustomAuthenticationEntryPoint customAuthenticationEntryPoint() { 
//  return new CustomAuthenticationEntryPoint(); 
// } 

@Bean 
public CustomExceptionTranslationFilter customExceptionTranslationFilter() { 
    return new CustomExceptionTranslationFilter(new CustomAuthenticationEntryPoint()); 
} 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     //Note : Able to login without this filter, but after adding this, valid credential also fails 
     .addFilterAfter(customExceptionTranslationFilter(), ExceptionTranslationFilter.class) 
//  .exceptionHandling() 
//   .authenticationEntryPoint(new customAuthenticationEntryPoint()) 
//   .and() 
     .authorizeRequests() 
      .anyRequest().authenticated() 
      .and() 
     .requestCache() 
      .requestCache(new NullRequestCache()) 
      .and() 
     .httpBasic() 
      .and() 
     .csrf().disable(); 
} 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(new CustomAuthenticationProvider()); 
    } 
} 

CustomAuthenticationProvider

@Component 
public class CustomAuthenticationProvider implements AuthenticationProvider { 

public CustomAuthenticationProvider() { 
    super(); 
} 

@Override 
public Authentication authenticate(final Authentication authentication) throws AuthenticationException { 
    final String name = authentication.getName(); 
    final String password = authentication.getCredentials().toString(); 
    if (name.equals("admin") && password.equals("password")) { 
     final List<GrantedAuthority> grantedAuths = new ArrayList<>(); 
     grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER")); 
     final UserDetails principal = new User(name, password, grantedAuths); 
     final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths); 
     return auth; 
    } else { 
     throw new BadCredentialsException("NOT_AUTHORIZED"); 
    } 
} 

    @Override 
    public boolean supports(final Class<?> authentication) { 
     return authentication.equals(UsernamePasswordAuthenticationToken.class); 
    } 

} 

CustomExceptionTranslationFilter

@Component 
public class CustomExceptionTranslationFilter extends ExceptionTranslationFilter { 

    public CustomExceptionTranslationFilter(AuthenticationEntryPoint authenticationEntryPoint) { 
     super(authenticationEntryPoint); 
    } 
} 

CustomAuthenticationEntryPoint

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { 

    @Override 
    public void commence(HttpServletRequest request, HttpServletResponse response, 
      AuthenticationException authException) throws IOException, ServletException { 
     response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized."); 
    } 
} 

P/S:基本的な質問には申し訳ありませんが、私は春&春のセキュリティには本当に新しいです。

+0

&過去の問題の私の答えhttp://stackoverflow.com/questions/37063342/spring-security-with-restcontroller-jsonish-customauthenticationprovider-resp/37063583#37063583 – D0dger

+0

@ D0dgerを参照してください:与えられた答えてくれてありがとう。しかし、まだ同じエラーが残っています。有効な資格情報を持つログインも "AuthExceptionEntryPoint"をトリガーします。どのようなヒントでこれをデバッグするためにチェックすることができますか? – lxnx

+0

'org.springframework.security'パッケージのロギングをオンにし、それを質問に添付します(有効な資格情報が機能しない場合) – D0dger

答えて

3

AuthenticationEntryPointの設計は、認証を開始/開始することです。ただし、実装CustomAuthenticationEntryPointはこれを行いません。その代わりに、単に不正な応答を返すだけです。実装の詳細については、javadoc(AuthenticationEntryPoint)を参照してください。コンフィグレーションに基づいて

あなたは、認証のためのHTTP Basicを使用している:

protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
      .anyRequest().authenticated() 
      .and() 
     .httpBasic(); 
} 

この特定の構成は、自動的にAuthenticationEntryPointの実装であるBasicAuthenticationEntryPointを設定します。 BasicAuthenticationEntryPointは、http応答ヘッダーWWW-Authenticate: Basic realm="User Realm"を使用して認証します(server protocol)。

しかし、自分で設定しているのはCustomAuthenticationEntryPointなので、やりたいことではないBasicAuthenticationEntryPointが上書きされます。

other postは、この設定をお勧めします。

protected void configure(HttpSecurity http) throws Exception { 
    http 
     .authorizeRequests() 
      .anyRequest().authenticated() 
      .and() 
     .httpBasic() 
      .and() 
     .exceptionHandling().authenticationEntryPoint(new CustomAuthenticationEntryPoint()); 
} 

あなたの主な目標は、私が設定さAuthenticationFailureHandlerとフォームログイン構成を提案するよりも、認証に失敗した場合、ユーザーにカスタム応答を提供することを目的とする場合。ここでの設定は以下のとおりです。DefaultAuthenticationFailureHandler

http 
    .authorizeRequests() 
     .anyRequest().authenticated() 
     .and() 
    .formLogin().failureHandler(new DefaultAuthenticationFailureHandler()) 
     .and() 
    .csrf().disable(); // NOTE: I would recommend enabling CSRF 

あなたの実装では、次のようになります。

public class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandler { 

    @Override 
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { 
     // Set status only OR do whatever you want to the response 
     response.setStatus(HttpServletResponse.SC_FORBIDDEN); 
    } 
} 

AuthenticationFailureHandlerは、具体的に失敗した認証の試みを処理するように設計されています。

+0

提案に感謝します。私はこれを試してみたところ、すべてのリクエストは "/ login"にリダイレクトされました(302)。あなたの情報については、これは@RestController経由で通信するWebサービスです。 – lxnx

関連する問題