Announcement Announcement Module
Collapse
No announcement yet.
spring security, spring remoting, cas proxy authentication Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • spring security, spring remoting, cas proxy authentication

    Hello all,

    I'm new to spring security and CAS.

    My problem is following:
    I have 3 servers:
    - SrvA is CAS
    - SrvB is client web application
    - SrvC is another web application which provides remote services (via HttpInvoker).
    For now every application is running on single server (Tomcat).

    Everything is ok between SrvA and SrvB, but when I obtain ProxyTicket for SrvC and invoke remote service from SrvB with this ProxyTicket I get following error:

    Code:
    2011-02-28 07:35:35 org.apache.catalina.core.StandardWrapperValve invoke
    SEVERE: Servlet.service() for servlet appServlet threw exception
    org.apache.commons.httpclient.HttpException: Did not receive successful HTTP response: status code = 302, status message = [Moved Temporarily]
    	at org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor.validateResponse(CommonsHttpInvokerRequestExecutor.java:214)
    	at org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor.doExecuteRequest(CommonsHttpInvokerRequestExecutor.java:131)
    	at org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor.executeRequest(AbstractHttpInvokerRequestExecutor.java:136)
    	at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:192)
    	at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:174)
    	at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:142)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    	at $Proxy17.sayHello(Unknown Source)
    	at security.test.HomeController.home(HomeController.java:43)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:312)
    	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
    	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:95)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:79)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:119)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
    	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
    	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:165)
    	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    	at java.lang.Thread.run(Thread.java:619)
    Configuration for SrvB

    web.xml:
    Code:
    <?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" version="2.5">
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
    			/WEB-INF/security-context.xml
    			/WEB-INF/spring/appServlet/servlet-context.xml
    		</param-value>
      </context-param>
      <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.context.ContextLoaderListener</listener-class>
      </listener>
      <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
      </listener>
      <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>

  • #2
    security-context.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns:security="http://www.springframework.org/schema/security"
        xmlns="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.1.xsd">
    
        <security:global-method-security pre-post-annotations="enabled" secured-annotations="enabled">
         </security:global-method-security>
    
    	<security:http entry-point-ref="casAuthenticationEntryPoint" auto-config="true" use-expressions="true">
    		<security:intercept-url pattern="/**" access="hasRole('ROLE_TEST')" />
            <security:form-login default-target-url='/' always-use-default-target='true' />
            <security:logout invalidate-session="true" logout-success-url="https://10.128.17.191:8443/cas/logout" />
    		<security:custom-filter position="CAS_FILTER" ref="casAuthenticationFilter" />
    		<security:session-management invalid-session-url="/timeout.jsp">
                <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
            </security:session-management>
    	</security:http>
    
    	<security:authentication-manager alias="authenticationManager">
    		<security:authentication-provider ref="casAuthenticationProvider" />
    	</security:authentication-manager>
    
    	<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
    		<property name="service" value="https://10.128.17.191:8443/securityTest/j_spring_cas_security_check" />
    		<property name="sendRenew" value="false" />
    	</bean>
    
    	<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
    		<property name="authenticationManager" ref="authenticationManager" />
    		<property name="filterProcessesUrl" value="/j_spring_cas_security_check" />
    		<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
            <property name="proxyReceptorUrl" value="/secure/receptor" />
    	</bean>
    
    	<bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl" />
    
    	<bean id="casAuthenticationEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
    		<property name="loginUrl" value="https://10.128.17.191:8443/cas/login" />
    		<property name="serviceProperties" ref="serviceProperties" />
    	</bean>
    
    	<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
    		<property name="userDetailsService" ref="UserDetailsService" />
    		<property name="serviceProperties" ref="serviceProperties" />
    		<property name="ticketValidator">
    			<bean class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">
    				<constructor-arg index="0" value="https://10.128.17.191:8443/cas" />
    				<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
    				<property name="proxyCallbackUrl" value="https://10.128.17.191:8443/securityTest/secure/receptor" />
    				<property name="proxyRetriever">
    					<bean class="org.jasig.cas.client.proxy.Cas20ProxyRetriever">
    						<constructor-arg index="0" value="https://10.128.17.191:8443/cas" />
    						<constructor-arg index="1" value="utf-8" />
    					</bean>
    				</property>
    			</bean>
    		</property>
    		<property name="key" value="cas" />
    	</bean>
    </beans>
    servlet-context.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:mvc="http://www.springframework.org/schema/mvc"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:security="http://www.springframework.org/schema/security"
    	xsi:schemaLocation="
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
            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/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    
    	<context:spring-configured />
    	<context:annotation-config />
    	<context:component-scan base-package="security" />
    
    	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="prefix" value="/WEB-INF/views/" />
    		<property name="suffix" value=".jsp" />
    	</bean>
    
    	<bean id="remoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
    		<property name="serviceUrl" value="https://10.128.17.191:8443/securityTest2/remoting/RemoteTestService" />
    		<property name="serviceInterface" value="security.test2.service.RemoteTestService" />
    		<property name="httpInvokerRequestExecutor">
    		<!--
    			<bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />
    		-->
    			<bean class="org.springframework.security.remoting.httpinvoker.CasAuthenticationCommonsHttpInvokerRequestExecutor" />
    		</property>
    	</bean>
    
    	<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
    
    </beans>
    CasAuthenticationCommonsHttpInvokerRequestExecutor is custom. It extends CommonsHttpInvokerRequestExecutor and adds ProxyTicket as ticket to request.
    It's identical to brolin's at http://forum.springframework.org/sho...d.php?p=347818

    Comment


    • #3
      Configuration for SrvC

      web.xml:
      Code:
      <?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" version="2.5">
        <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>
      			/WEB-INF/security-context.xml
      			/WEB-INF/application-context.xml
      		</param-value>
        </context-param>
        <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <listener>
          <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
        </listener>
        <servlet>
          <servlet-name>appServlet</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
          <servlet-name>appServlet</servlet-name>
          <url-pattern>/</url-pattern>
        </servlet-mapping>
        <servlet>
          <servlet-name>remoting</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <load-on-startup>2</load-on-startup>
        </servlet>
        <servlet-mapping>
          <servlet-name>remoting</servlet-name>
          <url-pattern>/remoting/*</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>
      </web-app>
      security-context:
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns:security="http://www.springframework.org/schema/security"
          xmlns="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.1.xsd">
      
      	<security:global-method-security pre-post-annotations="enabled" />
      
      	<security:http realm="SecureRemoting" use-expressions="true" entry-point-ref="casAuthenticationEntryPoint" auto-config="true">
      		<!-- <security:http-basic /> -->
      		<security:intercept-url pattern="/remoting/RemoteTestService" access="hasRole('ROLE_USER')" />
      		<security:custom-filter position="CAS_FILTER" ref="casAuthenticationFilter" />
      	</security:http>
      
      	<!-- ==== CAS ==== -->
      	<security:authentication-manager alias="authenticationManager">
      		<security:authentication-provider ref="casAuthenticationProvider" />
      	</security:authentication-manager>
      
      	<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
      		<property name="service" value="https://10.128.17.191:8443/epubSecurityTest/j_spring_cas_security_check" />
      		<property name="sendRenew" value="false" />
      	</bean>
      
      	<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
      		<property name="authenticationManager" ref="authenticationManager" />
      		<property name="filterProcessesUrl" value="/j_spring_cas_security_check" />
      		<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
              <property name="proxyReceptorUrl" value="/secure/receptor" />
      	</bean>
      
      	<bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl" />
      
      	<bean id="casAuthenticationEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
      		<property name="loginUrl" value="https://10.128.17.191:8443/cas/login" />
      		<property name="serviceProperties" ref="serviceProperties" />
      	</bean>
      
      	<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
      		<property name="userDetailsService" ref="UserDetailsService" />
      		<property name="serviceProperties" ref="serviceProperties" />
      		<property name="ticketValidator">
      			<bean class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">
      				<constructor-arg index="0" value="https://10.128.17.191:8443/cas" />
      				<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
      				<property name="proxyCallbackUrl" value="https://10.128.17.191:8443/epubSecurityTest2/secure/receptor" />
      				<property name="proxyRetriever">
      					<bean class="org.jasig.cas.client.proxy.Cas20ProxyRetriever">
      						<constructor-arg index="0" value="https://10.128.17.191:8443/cas" />
      						<constructor-arg index="1" value="utf-8" />
      					</bean>
      				</property>
      			</bean>
      		</property>
      		<property name="key" value="cas" />
      	</bean>
      </beans>
      application-context:
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
      	xmlns:mvc="http://www.springframework.org/schema/mvc"
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      	xmlns:context="http://www.springframework.org/schema/context"
      	xmlns:security="http://www.springframework.org/schema/security"
      	xsi:schemaLocation="
              http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
              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/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
      
      	<context:spring-configured />
      	<context:annotation-config />
      	<context:component-scan base-package="security" />
      
      	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      		<property name="prefix" value="/WEB-INF/views/" />
      		<property name="suffix" value=".jsp" />
      	</bean>
      
      	<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
      	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
      
      </beans>
      remoting-servlet.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"
      	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">
      
      	<bean name="/RemoteTestService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
      		<property name="service" ref="RemoteTestService" />
      		<property name="serviceInterface" value="security.test2.service.RemoteTestService" />
      	</bean>
      
      </beans>
      Any help would be appreciated.

      Comment


      • #4
        A redirect will happen after you authenticate using proxy tickets and the CasAuthenticationFilter. You can configure the invoker to follow recirects, but if you want to avoid this overhead, you have a few options:

        1) Use Spring Security preauthentication and the provided CAS Filters. There is an example on the CAS website and in the Spring Security samples
        2) Refer to this post for how to put the changes into your code

        PS: you may want to vote for the issue i referenced

        Comment


        • #5
          Thank you for suggestions Rob.
          Unfortunately first doesn't work - I mean configure the invoker to follow redirections. When I change code to
          Code:
          @Override
          	protected PostMethod createPostMethod(HttpInvokerClientConfiguration config) throws IOException {
          		PostMethod postMethod = super.createPostMethod(config);
          		CasAuthenticationToken cat = (CasAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
          		String ticket = cat.getAssertion().getPrincipal()
          			.getProxyTicketFor("https://10.128.17.191:8443/securityTest2/j_spring_cas_security_check");
          		System.out.println("TICKET: " + ticket);
          		postMethod.addRequestHeader("ticket", new String(Base64.encode(ticket.getBytes())));
          		postMethod.setFollowRedirects(true);
          		return postMethod;
          	}
          I've got another exception:
          Code:
          2011-03-02 10:36:43 org.apache.catalina.core.StandardWrapperValve invoke
          SEVERE: Servlet.service() for servlet appServlet threw exception
          java.lang.IllegalArgumentException: Entity enclosing requests cannot be redirected without user intervention
          	at org.apache.commons.httpclient.methods.EntityEnclosingMethod.setFollowRedirects(EntityEnclosingMethod.java:225)
          	at org.springframework.security.remoting.httpinvoker.CasAuthenticationCommonsHttpInvokerRequestExecutor.createPostMethod(CasAuthenticationCommonsHttpInvokerRequestExecutor.java:24)
          	at org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor.doExecuteRequest(CommonsHttpInvokerRequestExecutor.java:127)
          	at org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor.executeRequest(AbstractHttpInvokerRequestExecutor.java:136)
          	at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:192)
          	at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:174)
          	at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:142)
          	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
          	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
          	at $Proxy17.sayHello(Unknown Source)
          	at security.test.HomeController.home(HomeController.java:43)
          	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          	at java.lang.reflect.Method.invoke(Method.java:597)
          	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
          	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
          	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
          	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
          	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
          	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
          	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
          	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
          	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
          	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
          	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:312)
          	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
          	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:95)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:79)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:119)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
          	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
          	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:165)
          	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
          	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
          	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
          	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
          	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
          	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
          	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
          	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
          	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
          	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
          	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
          	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
          	at java.lang.Thread.run(Thread.java:619)
          After some googling I found out if request is POST or PUT it doesn't support redirect (according to RFC2616).

          I still have to try these another options.
          Vote added.

          Comment


          • #6
            It isn't doing a redirect with a POST it is doing a GET after a POST (which is supported by most if not all browsers). I am not all that familiar with CommonsHttpInvokerRequestExecutor so I do not know if/how it would work in such a scenario. You likely do not want to do this anyways since there would be an extra request each time you want a protected resource. Additionally stateless authentication does not get used so you have to get a new proxy ticket each time. The branch does not require a redirect for proxy ticket authentication and it allows for stateless mode to be used when doing proxy ticket authentication.

            Just as an FYI there are integration tests at samples/cas/src/it/. You can run them using ../.../gradlew appTest or ../.../gradlew.bat appTest from the samples/cas folder. The tests will start up a CAS server and the cas sample application and test both service (using a browser) and proxy (using commons httpclient) authentication.

            Comment


            • #7
              Second attempt - failed
              I've used Spring Security preauthentication and the provided CAS Filters. Configuration from: CAS site with all necessary changes (urls and stuff) for SrvC security-context.xml

              Result - same as for the first time:
              Code:
              2011-03-03 15:28:57 org.apache.catalina.core.StandardWrapperValve invoke
              SEVERE: Servlet.service() for servlet appServlet threw exception
              org.apache.commons.httpclient.HttpException: Did not receive successful HTTP response: status code = 302, status message = [Moved Temporarily]
              	at org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor.validateResponse(CommonsHttpInvokerRequestExecutor.java:214)
              	at org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor.doExecuteRequest(CommonsHttpInvokerRequestExecutor.java:131)
              	at org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor.executeRequest(AbstractHttpInvokerRequestExecutor.java:136)
              	at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:192)
              	at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:174)
              	at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:142)
              	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
              	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
              	at $Proxy17.sayHello(Unknown Source)
              	at security.test.HomeController.home(HomeController.java:43)
              	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              	at java.lang.reflect.Method.invoke(Method.java:597)
              	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
              	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
              	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
              	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
              	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
              	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
              	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
              	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
              	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
              	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
              	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:312)
              	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
              	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:95)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:79)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:119)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
              	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324)
              	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:165)
              	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
              	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
              	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
              	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              	at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:65)
              	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
              	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
              	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
              	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
              	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
              	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
              	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
              	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
              	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
              	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
              	at java.lang.Thread.run(Thread.java:619)
              Tomorrow I'll try your 965 branch solution. Hope it will do the trick...
              I still have the feeling that I'm missing something...

              Comment


              • #8
                Hi Rob, finally I've got it working.
                Unfortunately your 965 branch solution ended as all others with 302 status code response.

                So I've decided to write custom filter based on your solution. This is it's raw version (changed/added methods)
                Code:
                package security.test2.cas.filter;
                
                import java.io.IOException;
                
                import javax.servlet.FilterChain;
                import javax.servlet.ServletException;
                import javax.servlet.ServletRequest;
                import javax.servlet.ServletResponse;
                import javax.servlet.http.HttpServletRequest;
                import javax.servlet.http.HttpServletResponse;
                
                import org.jasig.cas.client.authentication.AttributePrincipal;
                import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
                import org.jasig.cas.client.util.CommonUtils;
                import org.jasig.cas.client.validation.Assertion;
                import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;
                import org.jasig.cas.client.validation.TicketValidationException;
                import org.slf4j.Logger;
                import org.slf4j.LoggerFactory;
                import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
                import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
                import org.springframework.security.cas.ServiceProperties;
                import org.springframework.security.core.Authentication;
                import org.springframework.security.core.AuthenticationException;
                import org.springframework.security.core.codec.Base64;
                import org.springframework.security.core.context.SecurityContextHolder;
                import org.springframework.security.core.userdetails.UserDetails;
                import org.springframework.security.core.userdetails.UserDetailsService;
                import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
                
                import security.test2.sso.cas.CASAuthentication;
                import security.test2.sso.cas.CASPrincipalWrapper;
                
                public class CasFilter extends AbstractAuthenticationProcessingFilter {
                
                    private static final Logger logger = LoggerFactory.getLogger(CasFilter.class);
                
                    //~ Static fields/initializers =====================================================================================
                
                    /** Used to identify a CAS request for a stateful user agent, such as a web browser. */
                    public static final String CAS_STATEFUL_IDENTIFIER = "_cas_stateful_";
                
                    /**
                     * Used to identify a CAS request for a stateless user agent, such as a remoting protocol client (e.g.
                     * Hessian, Burlap, SOAP etc). Results in a more aggressive caching strategy being used, as the absence of a
                     * <code>HttpSession</code> will result in a new authentication attempt on every request.
                     */
                    public static final String CAS_STATELESS_IDENTIFIER = "_cas_stateless_";
                
                    /**
                     * The last portion of the receptor url, i.e. /proxy/receptor
                     */
                    private String proxyReceptorUrl;
                
                    /**
                     * The backing storage to store ProxyGrantingTicket requests.
                     */
                    private ProxyGrantingTicketStorage proxyGrantingTicketStorage;
                
                    private String artifactParameter = ServiceProperties.DEFAULT_CAS_ARTIFACT_PARAMETER;
                
                    private Cas20ProxyTicketValidator ticketValidator;
                
                    private String serverName;
                
                    private UserDetailsService userDetailsService;
                
                    //~ Constructors ===================================================================================================
                
                    public CasFilter() {
                        super("/j_spring_cas_security_check");
                    }
                
                    //~ Methods ========================================================================================================
                
                    @Override
                    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult)
                			throws IOException, ServletException {
                
                //		boolean continueFilterChain = proxyTicketRequest(serviceTicketRequest(request, response), request);
                //		if (!continueFilterChain) {
                //			super.successfulAuthentication(request, response, authResult);
                //			return;
                //		}
                
                		if (logger.isDebugEnabled()) {
                			logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
                		}
                
                		SecurityContextHolder.getContext().setAuthentication(authResult);
                
                		// Fire event
                		if (this.eventPublisher != null) {
                			eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
                		}
                
                	}
                
                	/* (non-Javadoc)
                	 * @see org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
                	 */
                    @Override
                	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
                
                		HttpServletRequest request = (HttpServletRequest) req;
                		HttpServletResponse response = (HttpServletResponse) res;
                
                		// refers to setting ticket at CasAuthenticationCommonsHttpInvokerRequestExecutor 
                		// if ticket is set by postMethod.addParameter it's not possible to get it by request.getParameter
                		String proxyTicket = request.getHeader(this.artifactParameter) != null
                			? new String(Base64.decode(request.getHeader(this.artifactParameter).getBytes())) : null;
                
                		logger.info("doFilter - URI: " + request.getRequestURI());
                		logger.info("doFilter - ticket: " + proxyTicket);
                
                		if (proxyTicket == null || "".equals(proxyTicket)) {
                			chain.doFilter(request, response);
                
                			return;
                		}
                
                		if (logger.isDebugEnabled()) {
                			logger.debug("Request is to process authentication");
                		}
                
                		Assertion assertion = null;
                		Authentication authResult = null;
                		try {
                			assertion = this.ticketValidator.validate(proxyTicket,
                				CommonUtils.constructServiceUrl(request, response, null, this.serverName, this.artifactParameter, true));
                
                			if (assertion != null) {
                				AttributePrincipal attributePrincipal = assertion.getPrincipal();
                				logger.info(attributePrincipal.getName());
                			} else {
                				return;
                			}
                
                		CASAuthentication authRequest = new CASAuthentication();
                	        authRequest.setAssertion(assertion);
                	        authRequest.setAuthenticated(true);
                	        authRequest.setTicket(proxyTicket);
                	        authRequest.setPrincipalWrapper(new CASPrincipalWrapper(assertion.getPrincipal().getName()));
                
                	        UserDetails userDetails = this.userDetailsService.loadUserByUsername(authRequest.getName());
                	        authRequest.getAuthorities().addAll(userDetails.getAuthorities());
                
                	        // TODO move code to some authentication provider
                	        authResult = authRequest;
                //	        authResult = this.getAuthenticationManager().authenticate(authRequest);
                //			authResult = attemptAuthentication(request, response);
                //			if (authResult == null) {
                //				// return immediately as subclass has indicated that it hasn't completed authentication
                //				return;
                //			}
                //			sessionStrategy.onAuthentication(authResult, request, response);
                		} catch (TicketValidationException failed) {
                			// TODO
                			return;
                		} catch (AuthenticationException failed) {
                			// Authentication failed
                			unsuccessfulAuthentication(request, response, failed);
                
                			return;
                		}
                
                		// Authentication success
                //		if (continueChainBeforeSuccessfulAuthentication) {
                //			chain.doFilter(request, response);
                //		}
                
                		successfulAuthentication(request, response, authResult);
                
                		chain.doFilter(request, response);
                	}
                
                    ...
                
                    public final void setArtifactParameter(final String artifactParameter) {
                        this.artifactParameter = artifactParameter;
                    }
                
                    public final void setTicketValidator(final Cas20ProxyTicketValidator ticketValidator) {
                    	this.ticketValidator = ticketValidator;
                    }
                
                    public final void setServerName(final String serverName) {
                    	this.serverName = serverName;
                    }
                
                    public final void setUserDetailsService(final UserDetailsService userDetailsService) {
                    	this.userDetailsService = userDetailsService;
                    }
                
                    ...
                }

                Comment


                • #9
                  security-context.xml
                  Code:
                  <?xml version="1.0" encoding="UTF-8"?>
                  
                  <beans xmlns:security="http://www.springframework.org/schema/security"
                      xmlns="http://www.springframework.org/schema/beans"
                      xmlns:p="http://www.springframework.org/schema/p"
                      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.1.xsd">
                  
                      <security:global-method-security pre-post-annotations="enabled" />
                  
                      <security:http realm="SecureRemoting" auto-config="true">
                          <security:intercept-url pattern="/remoting/**" />
                          <security:custom-filter position="CAS_FILTER" ref="casAuthenticationFilter" />
                      </security:http>
                  
                      <!-- ==== CAS ==== -->
                      <security:authentication-manager alias="authenticationManager" />
                  
                      <bean id="casAuthenticationFilter" class="security.test2.cas.filter.CasFilter">
                          <property name="authenticationManager" ref="authenticationManager" />
                          <property name="filterProcessesUrl" value="/j_spring_cas_security_check" />
                          <property name="ticketValidator" ref="ticketValidator" />
                          <property name="serverName" value="https://10.128.17.191:8443" />
                          <property name="userDetailsService" ref="UserDetailsService" />
                      </bean>
                  
                      <bean id="ticketValidator" class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">
                          <constructor-arg index="0" value="https://10.128.17.191:8443/cas" />
                          <!-- <property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" /> -->
                          <!-- <property name="proxyCallbackUrl" value="https://10.128.17.191:8443/securityTest2/secure/receptor" /> -->
                          <property name="acceptAnyProxy" value="true" />
                          <property name="proxyRetriever">
                              <bean class="org.jasig.cas.client.proxy.Cas20ProxyRetriever">
                                  <constructor-arg index="0" value="https://10.128.17.191:8443/cas" />
                                  <constructor-arg index="1" value="utf-8" />
                              </bean>
                          </property>
                      </bean>
                  
                  </beans>
                  And small change for remoting-servlet.xml
                  Code:
                  <?xml version="1.0" encoding="UTF-8"?>
                  <beans xmlns="http://www.springframework.org/schema/beans"
                  	xmlns:security="http://www.springframework.org/schema/security"
                  	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  	xmlns:context="http://www.springframework.org/schema/context"
                  	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/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
                  
                  	<context:component-scan base-package="security" />
                  	<security:global-method-security pre-post-annotations="enabled" />
                  
                  	<bean name="/RemoteTestService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
                  		<property name="service" ref="RemoteTestService" />
                  		<property name="serviceInterface" value="security.test2.service.RemoteTestService" />
                  	</bean>
                  
                  </beans>
                  Firstly I was still getting 302 response, but after I've commented first part of successfulAuthentication method (especially: super.successfulAuthentication(request, response, authResult); ) it started to work as desired.

                  Of course this is configuration on the SrvC side. On SrvB everything remains unchanged.

                  Thanks for all your help!
                  Piotr

                  Comment


                  • #10
                    Originally posted by piotrj View Post
                    Firstly I was still getting 302 response, but after I've commented first part of successfulAuthentication method (especially: super.successfulAuthentication(request, response, authResult); ) it started to work as desired.
                    I'm glad you got this working. It may be good to figure out why this is not working for you so that we can ensure that when SEC-965 is completed it will fix your problem and you will not need to maintain a custom code base. There are a few things to check:
                    • What URL are you submitting the proxy ticket to? If the request was submitted to the filterProcessUrl (/j_spring_cas_security_check) regular service ticket authentication is performed which will do redirects.
                    • Did you ensure to set authenticateAllArtifacts property to true as is done in the sample?
                    • I also noticed that you are looking in the request headers for the proxy ticket. I am not aware of this being part of the specification. As far as I know the proxy ticket should be present as a HTTP parameter. Is there any documentation that you have found that allows the ticket to be specified as a header?
                      Originally posted by piotrj View Post
                      Code:
                      		String proxyTicket = request.getHeader(this.artifactParameter) != null
                      			? new String(Base64.decode(request.getHeader(this.artifactParameter).getBytes())) : null;

                    Comment


                    • #11
                      Originally posted by rwinch View Post
                      [*] What URL are you submitting the proxy ticket to? If the request was submitted to the filterProcessUrl (/j_spring_cas_security_check) regular service ticket authentication is performed which will do redirects.
                      Exactly - my request is submitted to filterProcessUrl (/j_spring_cas_security_check)

                      Code:
                      public class CasAuthenticationCommonsHttpInvokerRequestExecutor extends
                      		CommonsHttpInvokerRequestExecutor {
                      	
                      	@Override
                      	protected PostMethod createPostMethod(HttpInvokerClientConfiguration config) throws IOException {
                      		PostMethod postMethod = super.createPostMethod(config);
                      		String ticket = ((CasAuthenticationToken)SecurityContextHolder.getContext().getAuthentication()).getAssertion().getPrincipal().getProxyTicketFor("https://10.128.17.191:8443/securityTest2/j_spring_cas_security_check");
                      		postMethod.addRequestHeader("ticket", new String(Base64.encode(ticket.getBytes())));
                      //		postMethod.addParameter("ticket", new String(Base64.encode(ticket.getBytes())));
                      		return postMethod;
                      	}
                      }
                      Originally posted by rwinch View Post
                      [*] Did you ensure to set authenticateAllArtifacts property to true as is done in the sample?
                      Yes, it was set to true

                      Originally posted by rwinch View Post
                      [*] I also noticed that you are looking in the request headers for the proxy ticket. I am not aware of this being part of the specification. As far as I know the proxy ticket should be present as a HTTP parameter. Is there any documentation that you have found that allows the ticket to be specified as a header?
                      I didn't find that in documentation. When I was setting ticket as parameter
                      Code:
                      postMethod.addParameter("ticket", new String(Base64.encode(ticket.getBytes())));
                      I was getting null when trying to get it out from request in filter. My guess is that why is difference in URL in filter. It was not /j_spring_cas_security_check but it was remote method's I invoke: /remoting/RemoteTestService. Parameter was somehow stripped off while processing? Not really sure, but when I changed it to request header it was present in request. Hope this will be helpful.

                      Comment


                      • #12
                        Thank you for your response. I'm not certain why if you followed the bullets I outlined and used the branched code why this would not work. As I mentioned before, there are integration tests using commons httpclient that demonstrate it working. I assume that you have tried submitting as a parameter when using the branch code to the URL you wanted (i.e. not the filterProcessUrl)? I'm trying to ensure that I did not miss something when implementing the code in this branch.

                        Originally posted by piotrj View Post
                        Exactly - my request is submitted to filterProcessUrl (/j_spring_cas_security_check)
                        If you are submitting to j_spring_cas_security_check, how are you getting your application to process the actual request you want? For example if the purpose of the request was to save a message, how are you getting this code to be invoked?

                        Originally posted by piotrj View Post
                        I didn't find that in documentation. When I was setting ticket as parameter
                        Code:
                        postMethod.addParameter("ticket", new String(Base64.encode(ticket.getBytes())));
                        I was getting null when trying to get it out from request in filter. My guess is that why is difference in URL in filter. It was not /j_spring_cas_security_check but it was remote method's I invoke: /remoting/RemoteTestService. Parameter was somehow stripped off while processing? Not really sure, but when I changed it to request header it was present in request.
                        So it sounds like you are using the header value as a work around.

                        Comment


                        • #13
                          I couldn't run this integration test - something was wrong about path - probably with 'Documents and Settings'.

                          I think the best way is to test my code yourself, so I send it.
                          security-remoting-cas.zip is my working version.
                          security-remoting-cas-965 is with branch - You have to add your code or add important dependecies (attachment with it was too big to send).
                          Maybe You will find what I did wrong or why it doesn't work as desired.

                          Comment


                          • #14
                            Thanks for providing feedback on this solution. This will help to ensure the feature works for those that need it. I will try and take a look at what yo have attached later tonight.

                            Do you mind describing the issue you had with running the sample? What OS (I'm guessing Windows) and what OS version do you use? A complete stack trace and logs would be helpful. You can get more information if you use ..\..\gradlew.bat -d -S appTest.

                            Thanks again for your contributions back,

                            Comment


                            • #15
                              No problem.

                              My OS: Windows XP Professional with Service Pack 2
                              Log in attachment.

                              I'm not familiar with gradle. Honestly speaking I didn't know such thing exists until now. So forgive my ignorance if the problem is trivial.

                              Comment

                              Working...
                              X