2017-05-24 13 views
1

LDAPを使用してアクティブなディレクトリに対してユーザーを認証するためのログインフォームがあります。私はこれを行うためにApache Shiroを使用しています(これは重要なことではないと信じていますが、私が仕事に挑戦しようとするものに影響を与える可能性があるので、ユーザーが間違ったパスワードを入力した場合、私のフォームがある同じページにエラーメッセージを表示したいという例外がスローされています。したがって私はエラーメッセージを指定するところで推奨されるカスタム例外ハンドラを書きました。同じページにエラーメッセージを表示します

public String login() { 
     currentUser = ldapUserProvider.provide(); //gets Apache Shiro's Subject which is the user being authenticated. 
     if (!currentUser.isAuthenticated()) { 
      CustomUsernamePasswordToken token = new CustomUsernamePasswordToken(DOMAIN, user.getUserName(), user.getPassword()); 
      token.setRememberMe(true); 
      try { 
       currentUser.login(token); //this one causes exception if the password is wrong, for example 
       loggedIn = true; 
       return "success.xhtml"; 
      } catch (Exception e) { 
       return "index.xhtml"; //in this case I'd like to show the error message and prompt to login again 
      } 
     } 
     return "index.xhtml"; 
    } 

カスタムexceptionHandlerの:

package com.flyeralarm.tools.apss; 

import javax.faces.application.FacesMessage; 
import javax.faces.context.ExceptionHandler; 
import javax.faces.context.ExceptionHandlerWrapper; 
import javax.faces.context.FacesContext; 
import javax.faces.context.Flash; 
import javax.faces.event.ExceptionQueuedEvent; 
import javax.faces.event.ExceptionQueuedEventContext; 
import java.util.Iterator; 

public class AuthenticationExceptionHanlder extends ExceptionHandlerWrapper { 
    private ExceptionHandler wrappedExceptionhandler; 

    public AuthenticationExceptionHanlder(final ExceptionHandler wrappedExceptionhandler) { 
     this.wrappedExceptionhandler = wrappedExceptionhandler; 
    } 

    @Override 
    public ExceptionHandler getWrapped() { 
     return wrappedExceptionhandler; 
    } 

    @Override 
    public void handle() { 
     Iterator<ExceptionQueuedEvent> eventIterator = getUnhandledExceptionQueuedEvents().iterator(); 
     while (eventIterator.hasNext()) { 
      ExceptionQueuedEvent event = eventIterator.next(); 
      ExceptionQueuedEventContext eventContext = (ExceptionQueuedEventContext) event.getSource(); 
      Throwable exception = eventContext.getException(); 
      handleException(exception, eventContext); 
      eventIterator.remove(); 
      getWrapped().handle(); 
     } 
    } 

    private void handleException(Throwable exception, ExceptionQueuedEventContext context) { 
     FacesMessage exceptionMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Login failed.", exception.getMessage()); 
     FacesContext facesContext = FacesContext.getCurrentInstance(); 
     Flash flash = facesContext.getExternalContext().getFlash(); //I read that putting the message into flash would do the work but it didn't 
     flash.put("errorDetails", exception.getMessage()); 
     facesContext.addMessage(null, exceptionMessage); 
     facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "index?faces-redirect=true"); 
    } 
} 
LoginControllerクラスから

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:f="http://xmlns.jcp.org/jsf/core" 
     xmlns:h="http://xmlns.jcp.org/jsf/html" 
> 

<h:form> 
    <h:messages globalOnly="false"/> 
    <h:panelGrid columns="2"> 
     <h:outputLabel for="username">Username:</h:outputLabel> 
     <h:inputText id="username" value="#{user.userName}"/> 
     <h:outputLabel for="password">Password:</h:outputLabel> 
     <h:inputSecret id="password" value="#{user.password}"/> 
     <h:message for="username" infoStyle="color:darkgreen" errorStyle="color:red"/> 
     <h:message for="password" infoStyle="color:darkgreen" errorStyle="color:red"/> 
    </h:panelGrid> 
    <h:commandButton value="Login" action="#{loginController.login}" rendered="#{!loginController.loggedIn}"/> 
    <h:commandButton value="Logout" action="#{loginController.logout}" rendered="#{loginController.loggedIn}"/> 
</h:form> 
</html> 

ログイン方法:

いるindex.xhtml(私のログインフォーム):ここでは、コードの関連部分は、

また、グローバルのみ=真と偽で異なる組み合わせを試みましたが、私はカスタム例外ハンドラで定義したエラーメッセージを表示しません。私は優しさをしていますか?違う?

重複した質問に対する免責事項:私はSOサイトで可能な解決策を探して、別の回答の中で提案されたものを試しましたが、何も助けてくれませんでした。あなたのAuthenticationExceptionHanlder#handleException方法で

+0

私もこのトピックに移動するために始めている「AJAX」 – Kukeltje

+0

について学びます。 Rahulの解決策には何が間違っていたのですか?あなたは例外をキャッチしたときにメッセージを追加しませんでした。 – Al1

+0

ラインが実際に仕事をしたので、私はラフルの答えを受け入れます。私のコードの問題は、 'facesContext.getApplication()。getNavigationHandler()。handleNavigation(facesContext、null、" index?faces-redirect = true ");という行がページから離れているためです。行を削除すると、エラーメッセージが表示されました。 –

答えて

1

backing beanにメッセージを正しく追加した場合、globalOnlyスイッチが機能するはずです。クライアント-idがFacesContext.addMessage(...)でnullでなければなりません:

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message)); 
0

return "index.xhtml";から、おそらくエラーステータスが失われるので、あなたのページが完全にリロードされるために引き起こしているreturn null;にあなたのキャッチでリターンを変更してみてください、またはあなたが試すことができaddindこのライン

facesContext.getCurrentInstance().validationFailed(); 

ことjsfに検証エラーがあり、リフレッシュが起こらないようにする必要があります。

+0

残念ながら、どちらも助けになりませんでした。 –

関連する問題