Rohit Banga
Rohit Banga

Reputation: 18918

Spring Security j_spring_security_check not invoked

I have a Spring WebApp using custom User, Roles, Permissions tables custom (read "naive") authentication.

I am migrating the code to use Spring Security now. I read tutorials and got to the point where my login.jsp page, css, js, png files can be accessed ANONYMOUSLY. I have a form with action attribute as "j_spring_security_check". On submitting the form the browser performs an HTTP Post to this URL which results in a 404.

Now I am not mapping j_spring_security_check using RequestMapping. Is that required? When should we have a request mapping for this URL?

In my authentication provider I provide a reference to a bean of a class which implements UserDetailsService. I am expecting Spring to perform the authentication by invoking loadUserByUserName but this method never gets invoked. Why is the method not invoked? Have I misunderstood how authentication should work? Do I need to provide a custom request mapping for j_spring_security_check to make it work?

Here is my Custom User Details Service:

@Service(value="myUserDetailsService")
public class LoginUserService implements UserDetailsService {

  @Autowired
  private UserRepository userRepository;

  @Override
  public UserDetails loadUserByUsername(String username)
      throws UsernameNotFoundException {

    System.out.println("here");

    User user = userRepository.findUser(username);
    if (user != null)
      return new V2VUserDetails(user);
    else
      return null;
  }

}

Here is my security XML:

    <http pattern="/**/*.css" security="none" />
    <http pattern="/**/*.js" security="none" />
    <http pattern="/**/*.png" security="none" />

    <http auto-config="true">
      <intercept-url pattern="/login.html*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
      <intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY" />
      <intercept-url pattern="/**" access="ROLE_USER" />
      <form-login login-page="/login.html"
                  login-processing-url="/j_spring_security_check"
                  default-target-url="/welcomePage.html"
                  authentication-failure-url="/welcomePage.html"
                  always-use-default-target="true" />
    </http>

  <authentication-manager>
    <authentication-provider user-service-ref='myUserDetailsService'/>
  </authentication-manager>

  <beans:bean id="myUserDetailsService"
    class="security.LoginUserService">
  </beans:bean>

I checked several answers on Stackoverflow and other sites but could not fix the problem.

Edit Tried the suggestion given here. Now getting BeanFactory not initialized error.

Edit contextConfigLocation /WEB-INF/security-v2v-servlet.xml

<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>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
</filter-mapping>

Update

Current web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="WebApp_ID" version="2.5">

    <display-name>Spring3MVC</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/security-v2v-servlet.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <error-page>
        <error-code>500</error-code>
        <location>/errorPage.jsp</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/errorPage.jsp</location>
    </error-page>

    <servlet>
        <servlet-name>v2v</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>Resource Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.ResourceServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>v2v</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>v2v</servlet-name>
        <url-pattern>*.zip</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.jpeg</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.gif</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.png</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/j_spring_security_check</url-pattern>
    </servlet-mapping>

    <filter>
      <filter-name>UserAddFilter</filter-name>
      <filter-class>
          filter.UserInfoAddToThreadFilter
      </filter-class>
    </filter>
    <filter-mapping>
      <filter-name>UserAddFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-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>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>FORWARD</dispatcher>
    </filter-mapping>



    <listener>
      <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

</web-app>

Upvotes: 3

Views: 32625

Answers (2)

Michael
Michael

Reputation: 10319

  1. Please ensure you have in the login form action j_spring_security_check
  2. Not related to your problem but I recommend to remove the anonymous permission from /j_spring_security_check (remove the following line). Only the login form should have the anonymous permission. <intercept-url pattern="/j_spring_security_check" access="IS_AUTHENTICATED_ANONYMOUSLY" />

Update Please remove from web.xml

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/j_spring_security_check</url-pattern>
</servlet-mapping>

Upvotes: 0

Biju Kunjummen
Biju Kunjummen

Reputation: 49915

You don't need to create a @RequestMapping for /j_spring_security_check, that pattern is intercepted by Spring Security Filter and should direct you to your login page.

My guess on what is going wrong is that probably the way you have set up the Spring Security Filter. You should have the following entries in your web.xml for your filter:

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

and the Security config file should be loaded up through Root Web application context - one loaded through ContextLoaderListener NOT the one through DispatcherServlet, eg:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:/META-INF/context-security.xml</param-value>
</context-param>

If your configuration is along these lines, it should just work.

Upvotes: 4

Related Questions