2012-09-03 2 views
5

양식 기반 인증과 함께 HttpServletRequest.login을 사용하려고합니다.JSF 2.0 : HttpServletRequest.login을 사용한 후 보호 된 페이지로 리디렉션하는 방법

사용자가 로그인을 입력 한 후에 사용자가 요청한 보호 된 페이지로 사용자를 리디렉션하는 방법을 모르겠다는 것을 제외하면 모두 (로그인/비밀번호가 올바른지 여부를 컨테이너가 알립니다) 로그인 양식 다시 표시됩니다.) 그렇게하는 방법?

미리 도움을 주셔서 감사합니다.

코드 :

의 web.xml :

<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> 

업데이트

<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 : 아약스없이 작동하지 않습니다.

백업 콩 :

컨테이너 관리 폼 기반 인증 인 경우
@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)); 
    } 
    } 

} 

답변

5

는 로그인 페이지는 RequestDispatcher#forward() 원래 요청 URI에 의해 개방 커버 아래에 이름과 함께 요청 속성 따라서 사용할 RequestDispatcher#FORWARD_REQUEST_URI에 의해 식별됩니다. 요청 속성 (기본적으로 요청 범위)은 ExternalContext#getRequestMap()에 의해 사용 가능한 JSF에 있습니다. 따라서

,이 수행해야합니다

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 (JSF) 또는 @ConversationScoped (CDI)를 만드는 대신에 절대적으로 @SessionScoped (그리고 @RequestScoped해야하고, 그렇지 않으면 다른 방법이 사용되어야한다 <f:param><f:viewParam>).

+0

작동합니다 (requestedURI의 경우 String으로 캐스트 됨). 큰! BalusC, 나는 당신의 대답을 기다리고 있었다! 나는 당신의 기사를 오랫동안 읽었으며 나는 항상 매우 흥미롭고 매우 큰 전문 지식을 가지고 그들을 발견했다. 나는이 URI를 얻으려고했지만 좋은 가치를 얻을 수 없었다. 제출 전에 init 메소드가 시작된 솔루션은 매우 영리합니다. 당신의 도움을 주셔서 대단히 감사합니다. 귀하의 정보는 어디서 얻었습니까? 근원을 읽는가? – user1643352

+1

단지 주석 : 빈의 범위 **는 항상 사용자가 액세스하려고 시도한 첫 번째 보호 된 페이지와 동일한 페이지로 리다이렉트하므로 세션이되어서는 안됩니다. 보기 범위를 사용했습니다 (대화 범위보다 쉽습니다). 어떤 경우에 요청 된 URI가 null 일 수 있습니까? – user1643352

+1

어떻게 알 수 있듯이 컨테이너 관리 인증은 Servlet API spec/standard에 따라 작동하는 것입니다. 나는 JSF 옆에도 "평범한"JSP/Servlet에 익숙하다. 실제로 세션 범위는 이해하기 쉽습니다. 최종 사용자가 직접 로그인 페이지 자체를 요청한 경우 전달 요청 URI는 'null'일 수 있습니다. – BalusC

관련 문제