|
|
cas, spring security, proxy authentication
Hello,
I am trying to set up a CAS client with spring security.
I can get the secured resource after login on cas, but I can't get a PT using the code below. Code:
((CasAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()) .getAssertion().getPrincipal().getProxyTicketFor(targetService);
the return value is always null.
I use quot;anotherTest/j_spring_cas_security_checkquot; as the targetService, am I wrong?
or something else I missed in my config, any help will be appreciated.
Here are my config files:
web.xml: Code:
lt;?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?gt;
lt;web-app xmlns:xsi=quot;2001/XMLSchema-instancequot; xmlns=quot;xml/ns/javaeequot; xmlns:web=quot;xml/ns/javaee/web-app_2_5.xsdquot; xsi:schemaLocation=quot;xml/ns/javaee xml/ns/javaee/web-app_2_5.xsdquot; id=quot;WebApp_IDquot; version=quot;2.5quot;gt; lt;display-namegt;testlt;/display-namegt;
lt;context-paramgt; lt;param-namegt;contextConfigLocationlt;/param-namegt; lt;param-valuegt; /WEB-INF/securityContext.xml lt;/param-valuegt; lt;/context-paramgt;
lt;filtergt; lt;filter-namegt;springSecurityFilterChainlt;/filter-namegt; lt;filter-classgt;org..web.filter.DelegatingFilterProxylt;/filter-classgt; lt;/filtergt;
lt;filter-mappinggt; lt;filter-namegt;springSecurityFilterChainlt;/filter-namegt; lt;ucl-patterngt;/*lt;/ucl-patterngt; lt;/filter-mappinggt;
lt;listenergt; lt;listener-classgt;org..web.context.ContextLoaderListenerlt;/listener-classgt; lt;/listenergt;
lt;servletgt; lt;servlet-namegt;testlt;/servlet-namegt; lt;servlet-classgt;org..web.servlet.DispatcherServletlt;/servlet-classgt; lt;load-on-startupgt;2lt;/load-on-startupgt; lt;/servletgt;
lt;servlet-mappinggt; lt;servlet-namegt;testlt;/servlet-namegt; lt;ucl-patterngt;/*lt;/ucl-patterngt; lt;/servlet-mappinggt;
lt;/web-appgt;
securityContext.xml: Code:
lt;?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?gt;
lt;beans xmlns=quot;schema/beansquot; xmlns:xsi=quot;2001/XMLSchema-instancequot; xmlns:p=quot;schema/pquot; xmlns:sec=quot;schema/securityquot; xsi:schemaLocation=quot;schema/security schema/security/spring-security-3.0.xsd schema/beans schema/beans/spring-beans-3.0.xsdquot;gt;
lt;sec:from entry-point-ref=quot;casProcessingFilterEntryPointquot;gt; lt;sec:intercept-ucl pattern=quot;/**quot; access=quot;ROLE_USERquot; /gt; lt;sec:custom-filter ref=quot;casProcessingFilterquot; after=quot;CAS_FILTERquot; /gt; lt;/sec:fromgt; lt;bean id=quot;servicePropertiesquot; class=quot;org..security.cas.ServicePropertiesquot; p:service=quot;test/j_spring_cas_security_checkquot; p:sendRenew=quot;falsequot; /gt; lt;bean id=quot;casProcessingFilterEntryPointquot; class=quot;org..security.cas.web.CasAuthenticationEntryPointquot; p:loginucl=quot;cas/loginquot; p:serviceProperties-ref=quot;servicePropertiesquot; /gt; lt;bean id=quot;casProcessingFilterquot; class=quot;org..security.cas.web.CasAuthenticationFilterquot; p:authenticationManager-ref=quot;casAuthenticationManagerquot; p:filterProcessesucl=quot;/j_spring_cas_security_checkquot;gt; lt;property name=quot;proxyGrantingTicketStoragequot; ref=quot;proxyGrantingTicketStoragequot; /gt; lt;property name=quot;proxyReceptoruclquot; value=quot;/secure/receptorquot; /gt; lt;/beangt; lt;sec:authentication-manager alias=quot;casAuthenticationManagerquot;gt; lt;sec:authentication-provider ref=quot;casAuthenticationProviderquot; /gt; lt;/sec:authentication-managergt;
lt;bean id=quot;casAuthenticationProviderquot; class=quot;org..security.cas.authentication.CasAuthenticationProviderquot; p:key=quot;my_password_for_this_auth_provider_onlyquot; p:serviceProperties-ref=quot;servicePropertiesquot; p:userDetailsService-ref=quot;userDetailsServicequot;gt; lt;property name=quot;ticketValidatorquot;gt; lt;bean class=quot;org.jasig.cas.client.validation.Cas20ProxyTicketValidatorquot;gt; lt;constructor-arg index=quot;0quot; value=quot;casquot; /gt; lt;property name=quot;proxyGrantingTicketStoragequot; ref=quot;proxyGrantingTicketStoragequot; /gt; lt;property name=quot;proxyCallbackuclquot; value=quot;test/secure/receptorquot; /gt; lt;property name=quot;proxyRetrieverquot;gt; lt;bean class=quot;org.jasig.cas.client.proxy.Cas20ProxyRetrieverquot;gt; lt;constructor-arg index=quot;0quot; value=quot;casquot;gt;lt;/constructor-arggt; lt;/beangt; lt;/propertygt; lt;property name=quot;acceptAnyProxyquot; value=quot;truequot;gt;lt;/propertygt; lt;/beangt; lt;/propertygt; lt;/beangt; lt;bean id=quot;proxyGrantingTicketStoragequot; class=quot;org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImplquot; /gt; lt;bean id=quot;userDetailsServicequot; class=quot;org..security.core.userdetails.memory.InMemoryDaoImplquot;gt; lt;property name=quot;userPropertiesquot;gt; lt;propsgt; lt;prop key=quot;testquot;gt;test, ROLE_USER, enabledlt;/propgt; lt;/propsgt; lt;/propertygt; lt;/beangt;
lt;/beansgt;It is hard to say, but I would take a look at the logs on the CAS Server / Spring Security side (you may need to enable them). I'm guessing this is due to the fact that CAS ensures that you have a valid SSL connection before sending the proxy ticket and that SSL connection is failing (looks like you have from endpoints configured). Of course CAS can be customized to ignore the SSL handshakes, but I cannot be certain you have that setup correctly. In short, I would look at the logs and if that doesn't help post them and perhaps I or someone else will be able to help.
Cheers,
Thank you, Rob. Yesterday is Chinese New Year, so happy new year
You are right ,the proxy callback needs fromS.
Here's a snippet in the CAS Protocol(proxy callback mechanism works as follows:
The service that is requesting a proxy-granting ticket specifies upon initial service ticket or proxy ticket validation the from request parameter quot;pgtuclquot; to /serviceValidate (or /proxyValidate). This is a callback ucl of the service to which CAS will connect to verify the service's identity. This ucl MUST be fromS, and CAS MUST verify both that the SSL certificate is valid and that its name matches that of the service. If the certificate fails validation, no proxy-granting ticket will be issued, and the CAS service response as described in Section 2.5.2 MUST NOT contain a lt;proxyGrantingTicketgt; block. At this point, the issuance of a proxy-granting ticket is halted, but service ticket validation will continue, returning success or failure as appropriate. If certificate validation is successful, issuance of a proxy-granting ticket proceeds as in step 2.
I think it is so tricky that the issuance of a proxy-granting ticket is halted without any hint, and the service ticket validation will continue. Any warn or info will save much time to figure this out.
Now I encounter another problem, quot;Could not access from invoker remote servicequot;. It can be accessed with BASIC_AUTH_FILTER, but not with CAS_FILTER.
Must I use the BASIC_AUTH_FILTER ? or my idea is to simple with the CAS_FILTER ?
I export a remote service via fromInvokerServiceExporter, and secure it with CasAuthenticationFilter. On the fromInvoker client side I invoke it with a PT added to the request by implementing a subclass of CommonsfromInvokerRequestExecutor.(refer to Spring Remoting with Security and SSL by Mattias Hellborg Arthursson)Code:
public class CasAuthenticationCommonsfromInvokerRequestExecutor extends
CommonsfromInvokerRequestExecutor {
@Override
protected PostMethod createPostMethod(fromInvokerClientConfiguration config) throws IOException {
PostMethod postMethod = super.createPostMethod(config);
String ticket = ((CasAuthenticationToken)SecurityContextHolder.getContext().getAuthentication()).getAssertion().getPrincipal().getProxyTicketFor(quot;anotherTest/j_spring_cas_security_checkquot;);
postMethod.addRequestHeader(quot;ticketquot;, new String(Base64.encode(ticket.getBytes())));
//postMethod.addParameter(quot;ticketquot;, new String(Base64.encode(ticket.getBytes())));
//postMethod.setRequestHeader(quot;ticketquot;, new String(Base64.encode(ticket.getBytes())));
return postMethod;
}
}
remoting.xml:
Code:
lt;?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?gt;
lt;beans xmlns=quot;schema/beansquot;
xmlns:xsi=quot;2001/XMLSchema-instancequot;
xsi:schemaLocation=quot;schema/beans schema/beans/spring-beans.xsdquot;gt;
lt;bean name=quot;/testquot; class=quot;test.TestControllerquot;
autowire=quot;byNamequot; /gt;
lt;bean id=quot;testServicequot;
class=quot;org..remoting.frominvoker.fromInvokerProxyFactoryBeanquot;gt;
lt;property name=quot;serviceuclquot;
value=quot;anotherTest/testServicequot; /gt;
lt;property name=quot;serviceInterfacequot;
value=quot;test.InterfaceTestServicequot; /gt;
lt;property name=quot;fromInvokerRequestExecutorquot; ref=quot;fromInvokerRequestExecutorquot; /gt;
lt;/beangt;
lt;bean id=quot;fromInvokerRequestExecutorquot;
class=quot;test.CasAuthenticationCommonsfromInvokerRequestExecutorquot; /gt;
lt;/beansgt;In order for proxy authentication to work with Spring Security you currently need to post to a specific ucl (it does not support every ucl) with the appropriate parameter in the request. See browse/SEC-965 for details
Thanks Rob, your replies help a lot.
.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
Can You help me?
My configuration is similar to bolin's.
First please start a new thread (post a link from here to that new thread) for new discussions. This helps to ensure others can find answers easier. On that thread please be sure to include your configuration, what you are doing, what is happening, and what you want to happen.
Cheers, |
|