Spring Security and JSF, Failed to find resource /j_spring_security_check.jsp
I am having a little trouble getting Spring Security and JSF to work together properly. I have created a basic login page that returns a "login" outcome when the Login button is clicked. However, I am getting a 404, "Failed to find resource /j_spring_security_check.jsp." For some reason, it is tacking a .jsp at the end of my specified in my faces-config. I was able to get this working by doing a code-side redirect in an action method (ie: context.redirect(root + "/j_spring_security_check?j_username=" + userName + "&j_password=" + password); ). I would really like to put the j_spring_security_check in my faces-config, though. My code is shown below:
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>BBB_WEB</display-name>
<context-param>
<description>
Comma-delimited list of context-relative resource paths
under which the JSF implementation will look for application
configuration resources, before loading a co开发者_开发问答nfiguration
resource named /WEB-INF/facesconfig.xml (if such a resource
exists).
</description>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value></param-value>
</context-param>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jsp</param-value>
</context-param>
<!-- <context-param>-->
<!-- <param-name>facelets.LIBRARIES</param-name>-->
<!-- <param-value>/WEB-INF/tomahawk.taglib.xml</param-value>-->
<!-- </context-param>-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
classpath:applicationContext-security.xml
</param-value>
</context-param>
<context-param>
<description>
The location where state information is saved. Valid values
are 'server' (typically saved in HttpSession) and 'client'
(typically saved as a hidden field in the form. Default is
server.
</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<description>
Number of Views to be stored in the session when Server-Side
State Saving is being used. Default is 15.
</description>
<param-name>
com.sun.faces.NUMBER_OF_VIEWS_IN_SESSION
</param-name>
<param-value>15</param-value>
</context-param>
<context-param>
<description>
If set to true while server-side state saving is being used,
a serialized representation of the view is stored on the
server. This allows for failover and sever clustering
support. Default is false. This parameter is not available
in JSF 1.0.
</description>
<param-name>com.sun.faces.enableHighAvailability</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<description>
If set to true while client-side state saving is being used,
reduces the number of bytes sent to the client by
compressing the state before it is encoded and written as a
hidden field. Default is false. This parameter is not
available in JSF 1.0.
</description>
<param-name>com.sun.faces.COMPRESS_STATE</param-name>
<param-value>false</param-value>
</context-param>
<listener>
<listener-class>
com.sun.faces.config.ConfigureListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>/jsp/public/login.jsf</welcome-file>
</welcome-file-list>
</web-app>
faces-config
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<!-- =========== FULL CONFIGURATION FILE ================================== -->
<faces-config>
<application>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>
<navigation-rule>
<from-view-id>/jsp/*</from-view-id>
<!-- loginBean -->
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/j_spring_security_check</to-view-id>
</navigation-case>
<navigation-case>
<from-action>#{loginBean.newAccountAction}</from-action>
<from-outcome>success</from-outcome>
<to-view-id>/jsp/public/newAccount.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
login.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%-- jsf:pagecode language="java" location="/src/pagecode/jsp/public1/Login.java" --%><%-- /jsf:pagecode --%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<html>
<head>
<title>Login</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR" content="Rational Application Developer">
</head>
<f:view>
<body>
<h:form id="login">
<h:inputHidden id="sessionChecker" value="#{loginBean.sessionTrackerValue}" />
<%@ include file="/jsp/public/header.jsp"%>
<div id="content">
<div id="headerImage">
<h:graphicImage id="headerImage" url="#{headerBean.headerImageUrl}"/>
</div>
<div id="colMerge">
<h2>
<h:outputText id="contentTitleText" value="#{loginBean.pageTitle}"/>
</h2>
<h:panelGrid columns="1">
<h:messages id="errorMsg"/>
<h:panelGroup>
<h:outputText value="Username " />
<h:inputText id="j_username" value="#{loginBean.userName}" />
</h:panelGroup>
<h:panelGroup>
<h:outputText value="Password " />
<h:inputSecret id="j_password" value="#{loginBean.password}"/>
</h:panelGroup>
<h:commandButton value="Login" action="login"/>
<h:commandLink value="New Account" action="#{loginBean.newAccountAction}">
<h:outputText id="newAccountLoginText" value="" />
</h:commandLink>
</h:panelGrid>
</div>
</div>
</h:form>
</body>
</f:view>
</html>
applicationContext-security
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<security:global-method-security secured-annotations="enabled" />
<security:http auto-config="true" access-denied-page="/jsp/public/loginError.jsf">
<security:intercept-url pattern="/jsp/public/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/jsp/player/**" access="ROLE_USER,ROLE_ADMIN" />
<security:intercept-url pattern="/jsp/admin/**" access="ROLE_ADMIN" />
<security:form-login
login-page="/jsp/public/login.jsf"
default-target-url="/jsp/player/myPicks.jsf"
authentication-failure-url="/jsp/public/login.jsf" />
<security:logout logout-url="/jsp/public/logout.jsf" logout-success-url="/jsp/public/login.jsf" />
</security:http>
<security:authentication-provider user-service-ref="userDetailsService">
</security:authentication-provider>
<bean id="userDetailsService" class="graz.bbb.service.UserDetailsServiceImpl">
<constructor-arg ref="playerDao"/>
</bean>
</beans>
Anyone have any ideas?
Are you running on Websphere? Are you getting this error?
Error 404: SRVE0190E: File not found: /j_spring_security_check
If so, you need to configure a Webcontainer custom property in your local server and set "com.ibm.ws.webcontainer.invokefilterscompatibility" to "true". I have the same problem running Spring Security 3.x in Websphere 6.1, and that fixed it.
You can read more at http://www-01.ibm.com/support/docview.wss?uid=swg24014758
By the way, I see that your error message is "Failed to find resource /j_spring_security_check.jsp.". You shouldn't have ".jsp" in that link, it should be just "/j_spring_security_check". Fix that, and it should work for you.
Comment or delete the following lines in Web.xml... that is making the default suffix to jsp...
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jsp</param-value>
</context-param>
Hope that worked. The question is a bit old but the fix might be helpful to others...
In your applicationContext-security xml file the logout URL must be like the following,
<security:logout invalidate-session="true" logout-success-url="/jsp/public/login.jsf" logout-url="/j_spring_security_logout" />
In login.jsp page if you specify the form tag in following manner it should work,
<form action="/jsp/public/j_spring_security_check" method="post">
<h:inputText id="j_username" value="#{loginBean.userName}" />
<h:inputSecret id="j_password" value="#{loginBean.password}"/>
<h:commandButton value="Login"/>
</form>
you can give a logout link in your loggedIn pages like this,
<a href="/jsp/public/j_spring_security_logout">Logout</a>
In facesConfig xml you need to have the following specified and no need of delegating resolver since API variable-resolver is deprecated after JSF 1.1.
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
精彩评论