Java – Spring Security and JSF, Failed to find resource /j_spring_security_check.jsp

jakarta-eejavajsfspringspring-security

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

Best Answer

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.

Related Topic