我正在开发一个包含以下内容的Web应用程序
我现在面临的问题很奇怪。
如果启用了Spring安全性,则在授予访问权限之前,需要对对其余Web服务的任何访问进行身份验证。我正在使用JWT令牌身份验证登录。但是,登录后我的网页会失败。即我的登录成功,但此后的任何操作都会产生invalid crsf token or null request error.
如果我的Spring安全性被禁用,我的休息服务不需要进行身份验证即可访问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 :(得分:0)
首先,您必须确保具有spring security 4 compatible * -security.xml和* -servlet.xml look at this
从您发布的security.xml的一部分,我可以看到您没有form-login标记。它应该是这样的
<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隐藏输入,因为Spring会自动将其注入请求标头和参数(如果您不禁用它),从第4季开始