Announcement Announcement Module
Collapse
No announcement yet.
AuthenticationToken is null after autheticated Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • AuthenticationToken is null after autheticated

    I am running JSF + Spring + Hibernate. I had the spring security with JSF working like a champ Saturday night before I went to bed. I woke up Sunday morning, and the Code Gremlins must have gotten into it while I was asleep. I probably botched something late Saturday night, but I prefer to blame the Code Gremlins.

    I thought it was because I was trying to inject a custom filter into the middle of the FilterChainProxy, which by the way was working at one point. I have since realized, I don't need that filter, so I have removed it. I stripped security down to mostly default settings, and it still does not work. I am currently getting the following in the log when I try to login from the login screen:

    Error
    Code:
    175770 [http-8080-1] DEBUG org.springframework.security.web.access.ExceptionTranslationFilter  - Access is denied (user is anonymous); redirecting to authentication entry point
    org.springframework.security.access.AccessDeniedException: Access is denied
    I have stepped through the source, and I have watched the UsernamePasswordAuthenticationFilter execute. It creates the UsernamePasswordAuthenticationToken, and I watch the token get set on the SecurityContextHolder.getContext(). However when you get to the AnonymousAuthenticationFilter and call SecurityContextHolder.getContext().getAuthenticati on(), the token is null, so it creates an AnonymousAuthenticationToken, and sets AnonymousAuthenticationToken on the SecurityContext.

    I am taking the default strategy configuration for the SecurityContextHolder. According to the spring security documentation, it is MODE_THREADLOCAL. I have verified this is the case by stepping through the code. One thing I have noticed that might be causing the AuthenticationToken to be null when it gets to AnonymousAuthenticationFilter is that it appears that the SecurityContext object, which holds the authentication token is a completely a new instance of SecurityContext between where the authentication token was set (UsernamePasswordAuthenticationFilter ) and where it was retrieved(AnonymousAuthenticationFilter).

    However, I am not sure why. I would think that that in MODE_THREADLOCAL that a single request would be a single thread, so the context should not change. But I could be misunderstaning how ThreadLocal works. When I stepped through the code, I do not see anything that indicates that I have been redirected, which might explain this behavior.

    I have included my spring-context.xml (main spring context file), spring-security.xml, web.xml, as they currently stand with this problem. Any help in resolving this problem would be greatly appreciated.


    spring-security.xml
    Code:
    <beans:beans xmlns="http://www.springframework.org/schema/security"
    	xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
               http://www.springframework.org/schema/security
               http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
    
    	<http auto-config="true">
    		<form-login login-processing-url="/j_spring_security_check" 
    			login-page="/login.jsf" 
    			default-target-url="/profile/index.jsf" 
    			authentication-failure-url="/login.jsf" />
    	
    		<intercept-url pattern="/admin/**" access="ROLE_SITE_ADMIN" />
    		<intercept-url pattern="/staff/**" access="ROLE_SITE_STAFF" />
    		<intercept-url pattern="/profile/**" access="IS_AUTHENTICATED_REMEMBERED" />
    		<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    	</http>
    	
    	<authentication-manager >
    	  	<authentication-provider>
          		<user-service>
            		<user name="site.admin" password="password" authorities="ROLE_SITE_ADMIN,ROLE_SITE_STAFF" />
            		<user name="site.staff" password="password" authorities="ROLE_SITE_STAFF" />
          		</user-service>
        	</authentication-provider>
    	</authentication-manager>
    </beans:beans>
    web.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
     <description>Sample application</description>
     <display-name>richfaces-start</display-name>
     <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/config/spring-context.xml</param-value>
     </context-param>
     <context-param>
      <param-name>facelets.DEVELOPMENT</param-name>
      <param-value>true</param-value>
     </context-param>
     <context-param>
      <param-name>facelets.REFRESH_PERIOD</param-name>
      <param-value>2</param-value>
     </context-param>
     <context-param>
      <param-name>facelets.SKIP_COMMENTS</param-name>
      <param-value>true</param-value>
     </context-param>
     <context-param>
      <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
      <param-value>.xhtml</param-value>
     </context-param>
     <context-param>
      <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
      <param-value>server</param-value>
     </context-param>
     <context-param>
      <param-name>log4jConfigLocation</param-name>
      <param-value>/WEB-INF/config/log4j.xml</param-value>
     </context-param>
     <context-param>
      <param-name>org.richfaces.SKIN</param-name>
      <param-value>laguna14</param-value>
     </context-param>
     <filter>
      <filter-name>springSecurityFilterChain</filter-name>
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
     </filter>
     <filter>
      <display-name>Ajax4jsf Filter</display-name>
      <filter-name>ajax4jsf</filter-name>
      <filter-class>org.ajax4jsf.Filter</filter-class>
     </filter>
     <filter-mapping>
      <filter-name>springSecurityFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
      <dispatcher>FORWARD</dispatcher>
      <dispatcher>REQUEST</dispatcher>
     </filter-mapping>
     <filter-mapping>
      <filter-name>ajax4jsf</filter-name>
      <servlet-name>Faces Servlet</servlet-name>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>FORWARD</dispatcher>
      <dispatcher>INCLUDE</dispatcher>
     </filter-mapping>
     <listener>
      <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
     </listener>
     <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
     </listener>
     <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</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>
    </web-app>
    spring-context.xml
    Code:
    <?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:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    	   http://www.springframework.org/schema/context 
    	   http://www.springframework.org/schema/context/spring-context-3.0.xsd
       	   http://www.springframework.org/schema/tx 
       	   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       	   http://www.springframework.org/schema/aop 
       	   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">         
    
    
    	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       		<property name="location" value="classpath:/app.properties"/>
    	</bean>
    
    	<tx:annotation-driven transaction-manager="transactionManager"/>
    	<context:annotation-config />
    	
    	<context:component-scan base-package="myapp.common" />
    	<context:component-scan base-package="myapp.service" />
    	<context:component-scan base-package="myapp.db" />
      	
      	<import resource="spring-data.xml" />
       	<import resource="spring-security.xml" />
       
    </beans>
    Last edited by chris.gastin; Jun 20th, 2011, 01:11 PM.

  • #2
    Here is my JSF login page and JSF doLogin() method should you think they are causing the problem.

    Code:
    	public String doLogin() throws IOException, ServletException
        {
    		 
            ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
            
            ServletRequest request = (ServletRequest) context.getRequest();
            
            RequestDispatcher dispatcher = request.getRequestDispatcher("/j_spring_security_check");
            ServletResponse response =  (ServletResponse) context.getResponse(); 
            dispatcher.forward(request,response);
     
            FacesContext.getCurrentInstance().responseComplete();
            
            return null;
        }
    HTML Code:
    <html xmlns="http://www.w3.org/1999/xhtml"
    	xmlns:rich="http://richfaces.org/rich"
    	xmlns:a4j="http://richfaces.org/a4j"
    	xmlns:ui="http://java.sun.com/jsf/facelets"
    	xmlns:h="http://java.sun.com/jsf/html"
    	xmlns:f="http://java.sun.com/jsf/core"
    	xmlns:c="http://java.sun.com/jstl/core">
    
    <ui:composition template="./template.xhtml">
    	<ui:define name="title">Login</ui:define>
    	<ui:define name="pageSpecificCss">
    		<link rel="stylesheet" href="#{request.contextPath}/css/login.css" type="text/css" />
    	</ui:define>
    	<ui:define name="header"/>
    	<ui:define name="content">
    		<rich:panel id="loginPanel">
    			<f:facet name="header">Login</f:facet>
    			<rich:messages layout="list" styleClass="errors">
    				<f:facet name="infoMarker">
                    	<h:graphicImage value="images/error.gif" style=""/>
                    </f:facet>
            	</rich:messages>
        		<h:form id="loginForm" prependId="false">
    				<label for="j_username"><h:outputText value="Username:" /><br />
    				</label>
    				<h:inputText id="j_username"/>
    				<br />
    				<br />
    				<label for="j_password"><h:outputText value="Password:" /><br />
    				</label>
    				<h:inputSecret id="j_password"/>
    
    				<br />
    				<br />
    				<label for="_spring_security_remember_me"> <h:outputText
    						value="Remember me" /> </label>
    				<h:selectBooleanCheckbox id="_spring_security_remember_me" />
    				<br />
    
    				<a4j:commandButton type="submit" id="login"
    					action="#{loginBean.doLogin}" value="Login" />
    					
    			</h:form>
    		</rich:panel>
    	</ui:define>
    </ui:composition>
    </html>

    Comment

    Working...
    X