Issue
I have two applications running on 2 different servers (one on tomcat and other on JBoss). Both these applications are connected to the same CAS server for authentication. Right now this CAS server also resides within the same JBoss.
Say:
App-1 --- is on tomcat and CASified
App-2 --- is on JBoss and CASified
CAS --- is on JBoss
Now that I am invoking an url of App-1 from a browser. The CAS login page comes up and after username/password is provided, the request now successfully enters the servlet of App-1. From this servlet code, I am trying to invoke a webservice that resides inside App-2.
Note: I use axis2 for this webservice and the axis2.war is also CASified
to the same CAS server for authentication.
I could not make this webservice call work no matter what I do. Is there a way to achieve this?
Note: If I call the CAS REST api with a hardcoded username/password, I am
getting the TGT, through which I am able to get the Service Ticket, with
which I am able to invoke that web-service. But I do not want to login again
with a hard-coded username or password. My webservice invocation should
happen with the already logged-in user only.
Solution
This is possible by using the CAS Proxy feature.
The link
https://wiki.jasig.org/display/CAS/Proxy+CAS+Walkthrough
helped a bit. But could not understand where to start with.
First take the CAS client jar from http://downloads.jasig.org/cas-clients/ . In my case I took cas-client-core-3.3.3.jar
jar. I have included this jar in my application war.
In the web.xml of my application I have included the following 3 CAS Filters.
<!-- CAS Filters -->
<filter>
<filter-name>CAS Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://cas-hostname.domainname:port/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>https://app-hostname.domainname:port</param-value>
</init-param>
<init-param>
<param-name>proxyCallbackUrl</param-name>
<param-value>https://app-hostname.domainname:port/app/ticket</param-value>
</init-param>
<init-param>
<param-name>proxyReceptorUrl</param-name>
<param-value>/app/ticket</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://cas-hostname.domainname:port/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>https://app-hostname.domainname:port</param-value>
</init-param>
</filter>
<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<!-- filter mappings -->
<filter-mapping>
<filter-name>CAS Validation Filter</filter-name>
<url-pattern>/app/*</url-pattern>
<url-pattern>/ticket</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/app/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
<url-pattern>/app/*</url-pattern>
</filter-mapping>
Note-1: The order of filter mapping should be as mentioned above. First CAS Validation filter mapping should come, followed by CAS Authentication Filter and last the CAS HttpServletRequest Wrapper filter.
Note-2: The URL pattern /ticket which is basically your proxy callback url need not be mentioned in the last two filters.
Once CAS client jar is included in the web-app and web.xml configured with these filters, then all the http requests go through these filters.
So once your http requests entered your servlet, then you can call the following code snippet to get a proxy ticket:
String proxyTicket = ((AttributePrincipal) req.getUserPrincipal())
.getProxyTicketFor(webservice_url);
req
is the HttpServletRequest Object and AttributePrincipal
is a class which is present in the cas-client-core-3.3.3.jar
This proxyTicket can then be appended to your web-service's URL as a query string like the following:
https://myother-webservice-app.com/ws/myData?ticket=<proxyTicket>
Once this URL is constructed, then you can make the web-service call programmatically.
Hope this helps.
Answered By - Parasu
Answer Checked By - Timothy Miller (JavaFixing Admin)