2016-12-17 4 views
-1

ユーザー認証が失敗した場合、春からカスタムメッセージを取得するさまざまな方法を試しました。ログイン失敗の理由はありません(BadCredential例外のみがポップされます)

<http auto-config="true" use-expressions="false"> 
    <intercept-url pattern="/**" access='ROLE_FUNCTION' /> 
    <form-login login-page="/login" 
      default-target-url="/welcome" 
      username-parameter="j_username" 
      password-parameter="j_password" 
      login-processing-url="/j_spring_security_check" 
      always-use-default-target="true" 
      authentication-success-handler-ref="authenticationSuccessHandler" 
      authentication-failure-handler-ref="authenticationFailureHandler" 
      /> 
    <logout logout-url="/j_spring_security_logout" logout-success-url="/login?logout" delete-cookies="JSESSIONID" /> 
    <access-denied-handler error-page="/accessDenied" /> 
    <csrf disabled="true"/> 
</http> 
<authentication-manager> 
    <authentication-provider user-service-ref="**userDetailsService**"> 
     <password-encoder ref="bcryptEncoder"/> 
    </authentication-provider> 
</authentication-manager> 
<beans:bean id="authenticationSuccessHandler" class="com.company.project.CustomAuthenticationSuccessHandler"/> 
<beans:bean id="**authenticationFailureHandler**" class="com.company.project.CustomAuthenticationFailureHandler"/> 
<beans:bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> 

Bean定義の抜粋が

実装 userDetails以下の通りであるXML構成

<spring.version>4.2.4.RELEASE</spring.version> 
<spring.security.version>4.0.3.RELEASE</spring.security.version> 

を使用して

サービス

@Service("userDetailsService") 
public class CustomUserDetailsService implements UserDetailsService { 
@Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     logger.info("Getting access details for user : {}", username); 
     UserDto userDto = null; 
     boolean accountNonExpired = true; 
     boolean accountNonLocked = true; 
     boolean credentialsNonExpired = true; 
     boolean enabled = true; 
     try { 
      userDto = userService.loginUser(username); 
      if (userDto == null) { 
       throw new UsernameNotFoundException("User not found"); 
      } 
      if (Active.Y != userDto.getActive()) { 
       enabled = false; 
       throw new BadCredentialsException("User account is inactive"); 
      } 
     } catch (BaseException be) { 
      throw new BadCredentialsException(be.getMessage().toLowerCase()); 
     } 

     UserContext context = new UserContext(); 
     context.setLoginId(username); 
     context.setName(userDto.getName()); 
     context.setPrincipleId(userDto.getId()); 

     List<GrantedAuthority> grantedAuthorities = getGrantedAuthorities(userDto); 
     String password = getActivePassword(userDto); 
     accountNonExpired = isAccountActive(userDto); 
     accountNonLocked = isAccountUnlocked(userDto); 
     credentialsNonExpired = isCredentialsActive(userDto); 

     return new UserLoginDetails(grantedAuthorities, password, username, accountNonExpired, accountNonLocked, credentialsNonExpired, enabled, context); 
    } 
} 

authenticationSuccessHandlerが正常に動作します。

authenticationFailureHandler

@Component 
    public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { 
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); 

    @Autowired 
    UserService userService; 

    @Override 
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException { 
     try { 
      // execute it when user enters wrong password, i.e loginAttempt ... 
     } catch (Exception e) { 
      // TODO: something 

     } 
     // TODO: how do I send message, if authenticationException. 
     redirectStrategy.sendRedirect(request, response, "/login?error"); 
     // clearAuthenticationAttributes(request); 
    } 

    protected void clearAuthenticationAttributes(HttpServletRequest request) { 
     HttpSession session = request.getSession(false); 
     if (session == null) { 
      return; 
     } 
     session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION); 
    } 
} 

は私が

JSPが

<c:set var="errorMessage" value="${sessionScope[\"SPRING_SECURITY_LAST_EXCEPTION\"].message}" /> 

は私が期待されるメッセージをブリーフィングしてみましょう次の行を使用していたエラーメッセージを表示するように。

  1. ユーザーが間違った資格情報を入力した場合、彼は、ユーザーアカウントがアクティブでない場合、ユーザーが許容なしを超えた場合、彼は「あなたのアカウントがアクティブでない」

  2. を を取得する必要があります 「無効な資格情報」

  3. を取得する必要があります。 の自分のアカウントがロックされますと、私の実装では、私が何をすべきか変更お知らせください修正されていない場合、彼は「あなたのアカウントは をロックされている」

を取得します試みます。

答えて

0

AuthenticationFailureHandlerをオーバーライドする場合は、SimpleUrlAuthenticationFailureHandlerを拡張することができます。既に例外を保存する方法があります。

protected final void saveException(HttpServletRequest request, AuthenticationException exception) { 
      if (forwardToDestination) { 
       request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception); 
      } else { 
       HttpSession session = request.getSession(false); 

       if (session != null || allowSessionCreation) { 
        request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception); 
       } 
      } 
     } 

リクエストまたはセッションに例外を保存すると、メッセージを取得できます。

${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message} 
+0

ありがとうChaoluo、それは動作します! –

関連する問題