2017-02-27 115 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