5

フォームベースの認証で HttpServletRequest.login を使用しようとしています。

ユーザーがログインを入力した後、ユーザーが要求した保護されたページにユーザーをリダイレクトする方法がわからないことを除いて、すべて問題ありません(ログインフォームが再表示されます)。どうやってするか?

よろしくお願いします。

コード:

web.xml:

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>security</realm-name>
    <form-login-config>
        <form-login-page>/faces/loginwithlogin.xhtml</form-login-page>
        <form-error-page>/faces/noaut.xhtml</form-error-page>
    </form-login-config>
</login-config>

ページ loginwithlogin.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Authentication</title>
    </h:head>
    <h:body>
        <h:form>
            Login :
            <h:inputText value="#{login.login}" required="true" />
            <p/>
            Mot de passe :
            <h:inputSecret value="#{login.password}" required="true" />
            <p/>
            <h:commandButton value="Connexion" action="#{login.submit}">
                 <f:ajax execute="@form" render="@form" />
            </h:commandButton>
            <h:messages />
        </h:form>
    </h:body>
</html>

更新: Ajax がないと機能しません。

バッキング Bean:

@Named
@SessionScoped
public class Login implements Serializable {
  private String login;
  private String password;
  // getters and setters 
  ...

  public void submit() {
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletRequest request = 
            (HttpServletRequest) context.getExternalContext().getRequest();
    try {
        request.login(login, mdp);
        context.addMessage(null, 
                new FacesMessage(FacesMessage.SEVERITY_INFO, 
                "OK", null));
    } catch (ServletException e) {
        context.addMessage(null, 
                new FacesMessage(FacesMessage.SEVERITY_ERROR, 
                "Bad login", null));
    }
  }

}
4

1 に答える 1

5

コンテナー管理フォーム ベースの認証の場合、ログイン ページは によって開かれたカバーの下にあるRequestDispatcher#forward()ため、元の要求 URI は によって識別される名前の要求属性として使用できますRequestDispatcher#FORWARD_REQUEST_URI。リクエスト属性 (基本的にはリクエスト スコープ) は、によって利用可能な JSF にありますExternalContext#getRequestMap()

したがって、これは次のようにする必要があります。

private String requestedURI;

@PostConstruct
public void init() {
    requestedURI = FacesContext.getCurrentInstance().getExternalContext()
        .getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);

    if (requestedURI == null) {
        requestedURI = "some/default/home.xhtml";
    }
}

public void submit() throws IOException {
    // ...

    try {
        request.login(username, password);
        externalContext.redirect(requestedURI);
    } catch (ServletException e) {
        context.addMessage(null, 
                new FacesMessage(FacesMessage.SEVERITY_ERROR, 
                "Bad login", null));
    }
}

@ViewScopedの代わりに Bean (JSF) または@ConversationScoped(CDI)を作成するだけで済みます@SessionScoped(絶対にそうではありません@RequestScoped。それ以外の場合は、 と で別のアプローチを使用する必要があります<f:param>) <f:viewParam>

于 2012-09-03T11:16:55.440 に答える