2017-02-27 112 views
0

我開發一個Web應用程序包括以下如何結合令牌認證和CRSF?

  • REST Web服務的(春4)| JWT令牌認證
  • 網頁(login.xhtml,index.xhtml)(JSF,primeface)| crsf

我現在面臨的問題很奇怪。

如果我的spring安全性已啓用,則在授予訪問權限之前,對所有其他Web服務的訪問都需要進行身份驗證。我正在爲我的登錄使用JWT令牌認證。但是我登錄後我的網頁會失敗。即我的登錄成功,但在此之後的任何操作都會導致我的休息服務無需通過身份驗證即可訪問Web服務,但我的網頁完美無缺。

如何將兩種解決方案集成在一起?

我所有的網頁已經包含以下內容:

<input type="hidden" name="${_csrf.parameterName}" 
       value="${_csrf.token}" /> 

的ApplicationContext-security.xml文件:

<http pattern="/auth/login" security="none" /> 
    <http pattern="/login.xhtml" security="none" /> 
    <http pattern="/index.xhtml" security="none" /> 
    <http pattern="/javax.faces.resource/**" security="none" /> 
    <http pattern="/RES_NOT_FOUND" security="none" /> 
    <http pattern="/img/**" security="none" /> 

    <sec:http auto-config="false" create-session="stateless" entry-point-ref="customEntryPoint" use-expressions="true"> 
     <intercept-url pattern="/admin/**"   access="hasRole('ADMIN') or hasRole('HQ')" /> 
     <intercept-url pattern="/audit/**"   access="hasRole('ADMIN')" /> 
     <intercept-url pattern="/request/**"  access="hasRole('ADMIN') or hasRole('HQ')" /> 
     <intercept-url pattern="/reporting/**"  access="hasRole('ADMIN') or hasRole('HQ')" /> 

     <sec:custom-filter ref="customAuthenticationFilter" 
      before="PRE_AUTH_FILTER" /> 

<!--  <sec:csrf disabled="true" /> --> 
    </sec:http> 

正如你可以看到我包括<http pattern="/index.xhtml" security="none" />,這樣我可以讓那是什麼功能在我的index.xhtml工作。但是現在我可以直接訪問index.xhtml。

有人可以建議如何解決這個問題嗎?

=====編輯。更多信息=====

要添加,這是我的登錄頁面和控制器。

login.xhtml:

<html lang="en" xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:ui="http://java.sun.com/jsf/facelets"> 

<h:head> 
    <title>BTS Upload</title> 
    <h:outputStylesheet library="css" name="bootstrap.min.css" /> 
    <h:outputScript library="js" name="jquery-1.11.1.min.js" /> 
    <h:outputScript library="js" name="bootstrap.min.js" /> 
</h:head> 

<!-- Css here --> 

<h:body> 
    <font color="red"> <h:outputLabel 
      value="${SPRING_SECURITY_LAST_EXCEPTION.message}" /> 
    </font> 

    <div class="container"> 
     <div class="row"> 
      <div class="col-sm-6 col-md-4 col-md-offset-4"> 
       <h1 class="text-center login-title">Sign in</h1> 
       <div class="account-wall"> 

        <h:graphicImage class="profile-img" library="images" 
         name="photo.png" /> 

        <h:form class="form-signin"> 
         <h:outputLabel value="Enter UserName:" /> 

         <h:inputText id="username" value="#{loginAction.username}" 
          required="true" requiredMessage="Please enter your username" 
          autofocus="true" class="form-control"></h:inputText> 

         <h:message for="username" id="msg" 
          errorStyle="color:red; display:block" /> 

         <br /> 
         <h:outputLabel value="Enter Password:" /> 
         <h:inputSecret id="password" value="#{loginAction.pwd}" 
          required="true" requiredMessage="Please enter your password" 
          class="form-control"></h:inputSecret> 

         <h:message for="password" id="msg1" 
          errorStyle="color:red; display:block" /> 

         <br /> 
         <br /> 

         <h:commandButton class="btn btn-lg btn-primary btn-block" 
          action="#{loginAction.login}" 
          value="Login"></h:commandButton> 

         <input type="hidden" name="${_csrf.parameterName}" 
          value="${_csrf.token}" /> 

        </h:form> 
       </div> 

      </div> 
     </div> 
    </div> 
</h:body> 
</html> 

控制器:

@ManagedBean(name="loginAction") 
@SessionScoped 
public class LoginAction extends BaseAction implements Serializable 
{ 
    private static final long serialVersionUID = 1094801825228386363L; 

    private String pwd; 
    private String msg; 
    private String username; 

    @ManagedProperty("#{accessControlService}") 
    private AccessControlService accessControlService; 

    public String getPwd() 
    { 
     return pwd; 
    } 

    public void setPwd(String pwd) 
    { 
     this.pwd = pwd; 
    } 

    public String getMsg() 
    { 
     return msg; 
    } 

    public void setMsg(String msg) 
    { 
     this.msg = msg; 
    } 

    public String getUsername() 
    { 
     return username; 
    } 

    public void setUsername(String user) 
    { 
     this.username = user; 
    } 

    //validate login and redirect to the specified website. 
    public String login() 
    { 

     System.out.println(); 
     System.out.println("Call Log in"); 

     if (username.equals("") || pwd.equals("")) 
     { 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, 
        "Incorrect Username and Password", "Please enter correct username and Password")); 
      return "login"; 
     } 

     boolean valid = false; 
     String token = ""; 

     try 
     { 
      token = accessControlService.isAuthorizedUser(username, pwd, PropertiesUtil.LoginType.WEB_BTS.ordinal(), this.getRequest()); 
     } 
     catch (Exception e) 
     { 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, 
        "Error", e.getLocalizedMessage())); 
     } 

     if(token.contains(PropertiesUtil.TOKEN_HEADER)) 
     { 
      valid = true; 
     } 

     if (valid) 
     { 
      HttpSession session = this.getSession(); 
      session.setAttribute("username", username); 
      session.setAttribute("token", token); 

      return "admin"; 
     } 
     else 
     { 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, 
        "Incorrect Username and Password", "Please enter correct username and Password")); 
      return "login"; 
     } 
    } 

    // logout event, invalidate session 
    public String logout() 
    { 
     System.out.println("**********************************************************"); 
     try 
     { 
      accessControlService.logout(getUsername(), PropertiesUtil.LoginType.WEB_BTS.ordinal(), getRequest()); 
      HttpSession session = this.getSession(); 
      session.invalidate(); 
     } 
     catch (Exception e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return "login"; 
    } 

    public AccessControlService getAccessControlService() 
    { 
     return accessControlService; 
    } 

    public void setAccessControlService(AccessControlService accessControlService) 
    { 
     this.accessControlService = accessControlService; 
    } 
} 

回答

0

首先,你必須確保你有春天的安全兼容4 * -security.xml和* -servlet.xml後綴look at this

從您發佈的security.xml部分中,我可以看到您沒有表單登錄標記。它應該是這樣的

<security:form-login default-target-url="/index" 
         login-page="/login" 
         username-parameter="j_username" 
         password-parameter="j_password" 
         login-processing-url="/j_spring_security_check" 
         authentication-failure-url="/login?login_error=1"/> 

你登錄JSP需要有行動j_spring_security_check觸發的過濾器鏈:

<form action="<c:url value="/j_spring_security_check"/>" method="POST"> ... 

你不需要CSRF隱藏輸入,因爲彈簧自動注入成請求頭和參數(如果你不禁用它)從春季4開始

+0

我已經用我的登錄頁面和控制器更新了我的帖子。我之前嘗試過表單登錄,但仍然不能正常工作,因爲我正在使用primeface。我其實有我自己的認證課程。如何修改上面的xml文件? – shadow