- 浏览: 232842 次
- 性别:
- 来自: 广东
文章分类
最新评论
-
wangmuchang:
解压需要密码
CAS单点登录之测试应用 -
ayang722:
首先就要在运行报表birt的IEngineTask中加入, J ...
birt配置动态数据源 -
lihong11:
very good!
js常用方法 -
qtlkw:
你共享出来为什么要密码?要密码为何要共享出来?汗
CAS单点登录之测试应用 -
lishouxinghome:
请问如何获得用户的Id呢,往指点
使用 CAS 在 Tomcat 中实现单点登录
The demo guide provides detailed instructions for setting up a multi-domain SSO demonstration for a quick start with CAS.
If unreadable in IE (no line wrap), try Firefox or just use the PDF utility.
Problem Statement
You would like to show-off Single Sign On (SSO) to your boss and team ASAP. You have no clue about SSL, server certificates etc. But you know enough of Java, J2EE, Tomcat that someone is paying you for it. However, no matter how hard you try, you keep getting errors with basic CAS system install documentation. This wiki page will shows you how to install and demonstrate CAS, first on your Windows PC and then to takes a step further and shows that you can do multi-domain (another Windows PC) SSO login as well using CAS. Except for Dilbert's boss, everyone should be reasonably impressed. If you have a team that grappled programmatically with multi-domain SSO authentication in any way shape or form they will worship you like a God. I am focussing on multi-domain because, if you have just one single tomcat instance in which you have all your applications, and would like to do SSO, you really don't need CAS at all (it would be overkill) just uncomment the following in your server.xml and you should be good to go (assuming your applications are setup to authenticate already):
<!--
Normally, users must authenticate themselves to each web app
individually. Uncomment the following entry if you would like
a user to be authenticated the first time they encounter a
resource protected by a security constraint, and then have that
user identity maintained across *all* web applications contained
in this virtual host.
-->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
Beginner Issues
Lets get some newbie stuff out of the way first. These are the source of most problems:
Using localhost as the server name. This is, by far, the most misleading aspect of CAS system documentation in various wiki cross-references below. A red flag should go up anytime you see localhost. Use the actual computer (server) name. Use of raw IP addresses is discouraged for some reason. On a Windows XP box, the actual computer name can be determined by clicking "Start", select "Settings", "Control Panel", "Performance & Maintenance", "System" and then finally clicking on the "Computer Name" tab. The "Full Computer Name" is your server name. Use it instead of localhost (or you will die...guaranteed). For purposes of this wiki, lets call the first computer with the CAS server "compA" and the other one, simply, "compB".
Being totally clueless about SSL. CAS is designed so you can hack SSL out of it. But any self-respecting multi-domain SSO architecture needs to feature SSL because it is fundamentally important that client applications are not "spoofed" into thinking that the user has already logged in. For this, we need trust established between server and client. To implement this, we use a technique that is analogous to most daily business transactions. When you cash a check or use a credit card, you are sometimes asked to show your driver license to prove you are who you say you are. In this case, the merchant and you trust the Department of Motor Vehicles (DMV), which is a mutually acceptable independent "Certification Authority". Browsers establish (and enforce) this type of mutually trustworthy transactions through the Secure Socket Layer (SSL) protocol. Besides digital signatures certifying servers and clients, SSL gives you data confidentiality through encryption and data integrity through message-specific codes...good stuff. For applications that are deployed within your development environments, you can "self-certify" this SSL transaction. However, for external facing applications, when you are in production dealing with third parties outside your own LAN, SSL must be certified by a trusted third party like Verisign, Thawte. Any more discussion of SSL is out of scope of this wiki...which will just get your demo going. But please plan to do the needed research into SSL and also ensure that your company can support this down the road (it costs a few hundred dollars per certificate, plus you need to be legit business with a real address, etc...).
Ambiguous JRE location. You may have installed Java SDK and Tomcat long, long time ago and are unclear which JRE your tomcat points to anymore, for instance. Or you may already be doing SSL. It is VERY critical you know your tomcat installation (crystal clear). Otherwise, the best course of action is to install from scratch for this demo. Proceed at your own risk if you are unclear on this and skip the JDK and tomcat installs in the wiki below. CAS is going to be a critical server component in your enterprise anyway. It needs a little more respect than a completely self-contained JSP application that is plopped into an existing tomcat as a war. CAS clients will have that luxury, but certainly not the server, which brings me to...
What is SOA? I don't think you need to be an Service Oriented Architecture (SOA) expert to use CAS but you need to have some idea. Just installing a CAS sever is not going to get the job done. You need to configure your client application somewhat to "consume" the SSO service provided by the CAS server. This is basic to distributed, loosely coupled interactions that characterize SOA. For a tomcat client application of CAS, this just means two things: add a few lines to your web.xml, drop a few jars files into your WEB-INF/lib and reload. It does not get any simpler than that. But it does mean that your old login page, if you had one, perhaps will be retired. Even more deeply, it means that your applications will have less information about the user than before. If you didn't care ok. But note that you will need to ensure that any roles, privileges etc are taken care of within client application. To mix authentication and authorization is a bad idea. CAS is designed to serve many masters and cannot possibly please everyone with the same exact code. I will show you below how you can get the SSO login username within a tomcat client application, but that it is all you will get out-of-the-box from CAS. Your client application will have to take it from there, as to what the user can or cannot see. And, remember that CAS does not do a tomcat login for you...it is within CAS that a user session is maintained, not the local application container. Even if you did not comprehend all that SOA, you may proceed for now, but I guarantee you will run up against that wall: "How do I know who logged in?". Answer: CAS supports that out-of-the-box. "How do I control what the user can see?". Answer: CAS does not (should not) do that for you...it just lets user in the door (or slams it shut). Your application will not (and should not) have even the password of the user to "play with". Client applications need to independently figure out roles/privileges. Unless, of course, you are willing to create rather exotic extensions or configurations of CAS itself. Note that CAS is open source, so you can certainly do whatever you want with it to suit your needs. Or, you may look into frameworks that play well with CAS like Acegi Security. But we are getting way ahead of ourselves.
With that preamble, let's begin...
Stepwise Instructions
Basically, recommend starting fresh with (instruction are for a Windows XP professional computers) with no JDK/JRE or Tomcat. Using Microsoft Internet Explorer Version 7.0.5730.11 to verify SSL etc.
Step 1: Install JDK Version
download jdk-1_5_0_11-windows-i586-p.exe from java.sun.com
conduct a typical installation, doing next, next, next
set JAVA_HOME system environment variable to, well, java home... C:\Program Files\Java\jdk1.5.0_11
Step 2: Used keytool to self-author a server certificate for DEMO
Reference: http://www.ja-sig.org/wiki/display/CAS/Solving+SSL+issues
Entire Command Prompt Dialog is below...
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\ukari>cd \program*
The filename, directory name, or volume label syntax is incorrect.
C:\Program Files>cd java
C:\Program Files\Java>cd jdk*
C:\Program Files\Java\jdk1.5.0_11>cd bin
C:\Program Files\Java\jdk1.5.0_11\bin>keytool -genkey -alias tomcat -keypass changeit -keyalg RSA
Enter keystore password: changeit
What is your first and last name?
[Unknown]: compA
What is the name of your organizational unit?
[Unknown]: Information Systems
What is the name of your organization?
[Unknown]: Pacific Disaster Center
What is the name of your City or Locality?
[Unknown]: Kihei
What is the name of your State or Province?
[Unknown]: HI
What is the two-letter country code for this unit?
[Unknown]: US
Is CN=localhost, OU=Information Systems, O=Pacific Disaster Center, L=Kihei, ST=HI, C=US correct?
[no]: yes
C:\Program Files\Java\jdk1.5.0_11\bin>keytool -export -alias tomcat -keypass changeit -file server.crt
Enter keystore password: changeit
Certificate stored in file <server.crt>
C:\Program Files\Java\jdk1.5.0_11\bin>keytool -import -file server.crt -keypass changeit -keystore ..\jre\lib\security\cacerts
Enter keystore password: changeit
Owner: CN=localhost, OU=Information Systems, O=Pacific Disaster Center, L=Kihei, ST=HI, C=US
Issuer: CN=localhost, OU=Information Systems, O=Pacific Disaster Center, L=Kihei, ST=HI, C=US
Serial number: 462030d8
Valid from: Fri Apr 13 15:39:36 HST 2007 until: Thu Jul 12 15:39:36 HST 2007
Certificate fingerprints:
MD5: CC:3B:FB:FB:AE:12:AD:FB:3E:D 5:98:CB:2E:3B:0A:AD
SHA1: A1:16:80:68:39:C7:58:EA:2F:48:59:AA:1D:73:5F:56:78:CE:A4:CE
Trust this certificate? [no]: yes
Certificate was added to keystore
C:\Program Files\Java\jdk1.5.0_11\bin>
CAS Server Name
In the above dialog, it is critical that you enter the CAS server name as the answer (compA) to the following question:
What is your first and last name?
[Unknown]: compA
At this stage we have a .keystore file created in C:\Documents and Settings\<user> and the %JAVA_HOME%\jre\lib\security\cacerts file with the corresponding certificate.
Step 3: Install Tomcat
Selected the Windows Installer version at http://tomcat.apache.org/download-55.cgi#5.5.23
When prompted for directory, changed it to C:\tomcat5.5.23
When prompted for applications, I added all examples, webapps etc. (useful for testing CAS)
When prompted for JRE, changed default to %JAVA_HOME%/jre (IMPORTANT: this should be home of new cacerts from step 2)
Clicked finish and verified tomcat running as a service and also by doing http://localhost:8080
Ensure that logs look very clean as well.
Set environment variable %CATALINA_HOME% as C:\tomcat5.5.23
Tomcat JRE Home
In the above dialog, it is critical in that you select the JRE home where you put the cacerts file in step 2. In this case, please note that we are using %JAVA_HOME%/jre
Step 4: Configure Tomcat server.xml
uncomment connector element for port 8443 (SSL)
add the parameters for keystoreFile, keystorePass, truststoreFile as shown below
bounce tomcat
<!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
<Connector port="8443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="C:/Documents and Settings/ukari/.keystore"
keystorePass="changeit"
truststoreFile="C:/Program Files/Java/jdk1.5.0_11/jre/lib/security/cacerts" />
Step 5: CASify HelloWorld Servlet
http://www.ja-sig.org/wiki/display/CASC/Using+CASFilter
[http://www.ja-sig.org/products/cas/client/javaclient/index.html]
verify that http://compA:8080/servlets-examples/servlet/HelloWorldExample works.
add the following to web.xml of the servlets-examples context.
<filter>
<filter-name>CAS Filter</filter-name>
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
<param-value>https://compA:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://compA:8443/cas/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>compA:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlet/HelloWorldExample</url-pattern>
</filter-mapping>
Step 6: Drop CAS Client jar into the servlets-examples context
URL: http://www.ibiblio.org/maven/cas/jars/
create the lib directory under servlets-examples/WEB-INF
download that casclient-2.1.1.zip into C:\Tomcat5.5.23\webapps\servlets-examples\WEB-INF\lib
RENAME the zip file to jar file.
Note that for Tomcat 6 you must also include commons-logging in the lib folder: http://www.ibiblio.org/maven/commons-logging/jars/commons-logging-1.0.4.jar
Step 7: Download and Deploy CAS
URL: http://www.ja-sig.org/products/cas/downloads/index.html
download the cas-server-3.0.7.zip file.
extract it all to c:\cas-server-3.0.7 directory.
copy cas.war from C:\cas-server-3.0.7\cas-server-3.0.7\target to C:\Tomcat5.5.23\webapps
(this deploys cas if tomcat is running...but just to be sure...step
Step 8. Clean start
stop tomcat, clear all logs, start tomcat
examine logs
stdout_20070413.log (looks "normal"):
2007-04-13 16:32:02,082 INFO [org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler] \- <No PasswordEncoder set. Using default: org.jasig.cas.authentication.handler.PlainTextPasswordEncoder>
2007-04-13 16:32:02,082 INFO [org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler] \- <No Class to Support set. Using default: org.jasig.cas.authentication.principal.UsernamePasswordCredentials>
2007-04-13 16:32:02,082 WARN [org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler] \- <org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler is only to be used in a testing environment. NEVER enable this in a production environment.>
2007-04-13 16:32:02,129 INFO [org.jasig.cas.ticket.proxy.support.Cas20ProxyHandler] \- <No UniqueTicketIdGenerator specified for org.jasig.cas.ticket.proxy.support.Cas20ProxyHandler. Using org.jasig.cas.util.DefaultUniqueTicketIdGenerator>
2007-04-13 16:32:04,316 INFO [org.jasig.cas.web.ServiceValidateController] \- <No successView specified. Using default of casServiceSuccessView>
2007-04-13 16:32:04,316 INFO [org.jasig.cas.web.ServiceValidateController] \- <No failureView specified. Using default of casServiceFailureView>
2007-04-13 16:32:04,363 INFO [org.jasig.cas.web.ServiceValidateController] \- <No authentication specification class set. Defaulting to org.jasig.cas.validation.Cas20ProtocolValidationSpecification>
2007-04-13 16:32:04,363 INFO [org.jasig.cas.web.ServiceValidateController] \- <No successView specified. Using default of casServiceSuccessView>
2007-04-13 16:32:04,363 INFO [org.jasig.cas.web.ServiceValidateController] \- <No failureView specified. Using default of casServiceFailureView>
2007-04-13 16:32:04,473 INFO [org.jasig.cas.web.flow.AuthenticationViaFormAction] \- <FormObjectClass not set. Using default class of org.jasig.cas.authentication.principal.UsernamePasswordCredentials with formObjectName credentials and validator org.jasig.cas.validation.UsernamePasswordCredentialsValidator.>
2007-04-13 16:32:22,223 INFO [org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner] \- <Starting cleaning of expired tickets from ticket registry at [Fri Apr 13 16:32:22 HST 2007]>
2007-04-13 16:32:22,223 INFO [org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner] \- <0 found to be removed. Removing now.>
2007-04-13 16:32:22,223 INFO [org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner] \- <Finished cleaning of expired tickets from ticket registry at [Fri Apr 13 16:32:22 HST 2007]>
catalina.2007-04-13.log (looks "normal"):
Apr 13, 2007 4:31:56 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Tomcat5.5.23\bin;.;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\ATI Technologies\ATI Control Panel;C:\Program Files\Common Files\Adobe\AGL
Apr 13, 2007 4:31:57 PM org.apache.coyote.http11.Http11BaseProtocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Apr 13, 2007 4:31:58 PM org.apache.coyote.http11.Http11BaseProtocol init
INFO: Initializing Coyote HTTP/1.1 on http-8443
Apr 13, 2007 4:31:58 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 2859 ms
Apr 13, 2007 4:31:58 PM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Apr 13, 2007 4:31:58 PM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/5.5.23
Apr 13, 2007 4:31:58 PM org.apache.catalina.core.StandardHost start
INFO: XML validation disabled
Apr 13, 2007 4:32:00 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive cas.war
Apr 13, 2007 4:32:06 PM org.apache.coyote.http11.Http11BaseProtocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Apr 13, 2007 4:32:07 PM org.apache.coyote.http11.Http11BaseProtocol start
INFO: Starting Coyote HTTP/1.1 on http-8443
Apr 13, 2007 4:32:07 PM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Apr 13, 2007 4:32:07 PM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/47 config=null
Apr 13, 2007 4:32:07 PM org.apache.catalina.storeconfig.StoreLoader load
INFO: Find registry server-registry.xml at classpath resource
Apr 13, 2007 4:32:07 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 8891 ms
localhost.2007-04-13.log (looks "normal"):
Apr 13, 2007 4:32:04 PM org.apache.catalina.core.ApplicationContext log
INFO: org.apache.webapp.balancer.BalancerFilter: init(): ruleChain: \[org.apache.webapp.balancer.RuleChain: [org.apache.webapp.balancer.rules.URLStringMatchRule: Target string: News / Redirect URL: http://www.cnn.com], [org.apache.webapp.balancer.rules.RequestParameterRule: Target param name: paramName / Target param value: paramValue / Redirect URL: http://www.yahoo.com], [org.apache.webapp.balancer.rules.AcceptEverythingRule: Redirect URL: http://jakarta.apache.org]\]
Apr 13, 2007 4:32:05 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Apr 13, 2007 4:32:05 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Apr 13, 2007 4:32:05 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Apr 13, 2007 4:32:05 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
All other log files stderr, admin, host-manager, jakarta_service, manager are of size 0K. Checked stderr just to make sure...
Step 9. Try It
Use fresh browser session to access http://compA:8080/servlets-examples/servlet/HelloWorldExample
Get past all browser alerts/warnings to CAS login page
Log in as uday/uday (or any username=password string)
Again see all sorts of alerts/warnings
See Hello World...success.
Logs
stdout_20070413.log (three new records):
2007-04-13 16:39:01,238 INFO [org.jasig.cas.web.flow.AutomaticCookiePathSetterAction] \- <Setting ContextPath for cookies to: /cas>
2007-04-13 16:39:18,271 INFO [org.jasig.cas.authentication.AuthenticationManagerImpl] \- <AuthenticationHandler: org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler successfully authenticated the user which provided the following credentials: uday>
2007-04-13 16:39:18,286 INFO [org.jasig.cas.CentralAuthenticationServiceImpl] \- <Granted service ticket [ST-2-V03EdNba1e3cMxeoEbEHwXfoefftIeeRxuO-20] for service [http://compA:8080/servlets-examples/servlet/HelloWorldExample] for user [uday]>
localhost.2007-04-13.log (new records):
Apr 13, 2007 4:38:51 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: sessionCreated('6ED4CFE9A5D7BA592372A3E67DF7D6E8')
Apr 13, 2007 4:38:51 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: attributeAdded('6ED4CFE9A5D7BA592372A3E67DF7D6E8', 'edu.yale.its.tp.cas.client.filter.didGateway', 'true')
Apr 13, 2007 4:38:51 PM org.apache.catalina.core.ApplicationContext log
INFO: InvokerFilter(ApplicationFilterConfig[name=Path Mapped Filter, filterClass=filters.ExampleFilter]): 31 milliseconds
Apr 13, 2007 4:39:19 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: attributeAdded('6ED4CFE9A5D7BA592372A3E67DF7D6E8', 'edu.yale.its.tp.cas.client.filter.user', 'uday')
Apr 13, 2007 4:39:19 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: attributeAdded('6ED4CFE9A5D7BA592372A3E67DF7D6E8', 'edu.yale.its.tp.cas.client.filter.receipt', '\[edu.yale.its.tp.cas.client.CASReceipt userName=[uday] casValidateUrl=[https://compA:8443/cas/serviceValidate] proxyCallbackUrl=[null] pgtIou=[null] casValidateUrl=[https://compA:8443/cas/serviceValidate] proxyList=\[\[\]\]\]')
Apr 13, 2007 4:39:19 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: attributeRemoved('6ED4CFE9A5D7BA592372A3E67DF7D6E8', 'edu.yale.its.tp.cas.client.filter.didGateway', 'true')
Apr 13, 2007 4:39:19 PM org.apache.catalina.core.ApplicationContext log
INFO: InvokerFilter(ApplicationFilterConfig[name=Path Mapped Filter, filterClass=filters.ExampleFilter]): 860 milliseconds
All other logs unchanged. Done (Success). Well sorta. This is the absolute minimal "proof-of-life" with Yale CAs. Still need to CAS-ify some other application and see if it works between two applications on separate machines...which leads us to...
Step 10: Setup up distinct domain
Repeat repeat Steps 1 thru 4 above for compB. Just do it, dont worry about creating a server certificate etc...Tomcat seems to like a keystore. So just do it.
Step 11: CAS-ify client on second domain slightly differently
In step 5, modify the direction above to add compB as the client-host as follows (obviously, leave the rest of it alone).
Server Name Specification
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>compB:8080</param-value>
</init-param>
Though not needed for this demo, I promised to show you how you may get the user. This is how. Add the following right after the server name specification as a child of the <filter> element and as a sibling of the above init-param element for server name. This entry will allow you to access the login user name as String username = request.getRemoteUser(); within any of the secured jsp. Try it!
Config for getting user name in request
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.wrapRequest</param-name>
<param-value>true</param-value>
</init-param>
Another useful tip is that you may secure as many resources as you wish within your context by simply adding the following:
Adding multiple secured resources
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlet/RequestHeaderExample</url-pattern>
</filter-mapping>
The final compB web.xml modifications should look as follows:
<filter>
<filter-name>CAS Filter</filter-name>
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
<param-value>https://compA:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://compA:8443/cas/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>compB:8080</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.wrapRequest</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlet/HelloWorldExample</url-pattern>
</filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlet/RequestHeaderExample</url-pattern>
</filter-mapping>
Step 12: Drop CAS Client jar into the servlets-examples context
Identical to Step 6, but for compB.
Step 13: Establish trust with CAS SSO Server
Ref: http://blogs.sun.com/andreas/entry/no_more_unable_to_find
Here is the most elegant way to do it, I think.
In compB, simply copy the cacerts to cacerts.old (to save it just in case)
run java InstallCert compA:8443 (i.e. provide the argument "compA:8443" to the executable "InstallCert")
(adapted source code for InstallCert.java from Sun blog by Andreas Sterbenz is shown below)
Answer 1 to the prompt
This will add compA into trust store of compB (while neatly obviating the problem discussed in the Sun blog referenced above).
InstallCert.java - adapted from Sun Microsystems blog by Andreas Sterbenz
/*
* @(#)InstallCert.java 1.1 06/10/09
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
import java.io.*;
import java.net.URL;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
public class InstallCert {
public static void main(String[] args) throws Exception {
String host;
int port;
char[] passphrase;
if ((args.length == 1) || (args.length == 2)) {
String[] c = args[0].split(":");
host = c[0];
port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
String p = (args.length == 1) ? "changeit" : args[1];
passphrase = p.toCharArray();
} else {
System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
return;
}
File file = new File("jssecacerts");
if (file.isFile() == false) {
char SEP = File.separatorChar;
File dir = new File(System.getProperty("java.home") + SEP
+ "lib" + SEP + "security");
file = new File(dir, "jssecacerts");
if (file.isFile() == false) {
file = new File(dir, "cacerts");
}
}
System.out.println("Loading KeyStore " + file + "...");
InputStream in = new FileInputStream(file);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(in, passphrase);
in.close();
SSLContext context = SSLContext.getInstance("TLS");
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
context.init(null, new TrustManager[] {tm}, null);
SSLSocketFactory factory = context.getSocketFactory();
System.out.println("Opening connection to " + host + ":" + port + "...");
SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
socket.setSoTimeout(10000);
try {
System.out.println("Starting SSL handshake...");
socket.startHandshake();
socket.close();
System.out.println();
System.out.println("No errors, certificate is already trusted");
} catch (SSLException e) {
System.out.println();
e.printStackTrace(System.out);
}
X509Certificate[] chain = tm.chain;
if (chain == null) {
System.out.println("Could not obtain server certificate chain");
return;
}
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
System.out.println();
System.out.println("Server sent " + chain.length + " certificate(s):");
System.out.println();
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
MessageDigest md5 = MessageDigest.getInstance("MD5");
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = chain[i];
System.out.println
(" " + (i + 1) + " Subject " + cert.getSubjectDN());
System.out.println(" Issuer " + cert.getIssuerDN());
sha1.update(cert.getEncoded());
System.out.println(" sha1 " + toHexString(sha1.digest()));
md5.update(cert.getEncoded());
System.out.println(" md5 " + toHexString(md5.digest()));
System.out.println();
}
System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
String line = reader.readLine().trim();
int k;
try {
k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
} catch (NumberFormatException e) {
System.out.println("KeyStore not changed");
return;
}
X509Certificate cert = chain[k];
String alias = host + "-" + (k + 1);
ks.setCertificateEntry(alias, cert);
OutputStream out = new FileOutputStream(file);
ks.store(out, passphrase);
out.close();
System.out.println();
System.out.println(cert);
System.out.println();
System.out.println
("Added certificate to keystore 'cacerts' using alias '"
+ alias + "'");
}
private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
private static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 3);
for (int b : bytes) {
b &= 0xff;
sb.append(HEXDIGITS[b >> 4]);
sb.append(HEXDIGITS[b & 15]);
sb.append(' ');
}
return sb.toString();
}
private static class SavingTrustManager implements X509TrustManager {
private final X509TrustManager tm;
private X509Certificate[] chain;
SavingTrustManager(X509TrustManager tm) {
this.tm = tm;
}
public X509Certificate[] getAcceptedIssuers() {
throw new UnsupportedOperationException();
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
throw new UnsupportedOperationException();
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
this.chain = chain;
tm.checkServerTrusted(chain, authType);
}
}
}
Step 14: Test
Clean logs, restart tomcat on compB.
Repeat Step 9.
Change compA to compB on the URL.
You should not be challenged to login (QED)
Restart tomcat and try again, you should have to login to compB
And, not to compA
Congratulations.
If unreadable in IE (no line wrap), try Firefox or just use the PDF utility.
Problem Statement
You would like to show-off Single Sign On (SSO) to your boss and team ASAP. You have no clue about SSL, server certificates etc. But you know enough of Java, J2EE, Tomcat that someone is paying you for it. However, no matter how hard you try, you keep getting errors with basic CAS system install documentation. This wiki page will shows you how to install and demonstrate CAS, first on your Windows PC and then to takes a step further and shows that you can do multi-domain (another Windows PC) SSO login as well using CAS. Except for Dilbert's boss, everyone should be reasonably impressed. If you have a team that grappled programmatically with multi-domain SSO authentication in any way shape or form they will worship you like a God. I am focussing on multi-domain because, if you have just one single tomcat instance in which you have all your applications, and would like to do SSO, you really don't need CAS at all (it would be overkill) just uncomment the following in your server.xml and you should be good to go (assuming your applications are setup to authenticate already):
<!--
Normally, users must authenticate themselves to each web app
individually. Uncomment the following entry if you would like
a user to be authenticated the first time they encounter a
resource protected by a security constraint, and then have that
user identity maintained across *all* web applications contained
in this virtual host.
-->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
Beginner Issues
Lets get some newbie stuff out of the way first. These are the source of most problems:
Using localhost as the server name. This is, by far, the most misleading aspect of CAS system documentation in various wiki cross-references below. A red flag should go up anytime you see localhost. Use the actual computer (server) name. Use of raw IP addresses is discouraged for some reason. On a Windows XP box, the actual computer name can be determined by clicking "Start", select "Settings", "Control Panel", "Performance & Maintenance", "System" and then finally clicking on the "Computer Name" tab. The "Full Computer Name" is your server name. Use it instead of localhost (or you will die...guaranteed). For purposes of this wiki, lets call the first computer with the CAS server "compA" and the other one, simply, "compB".
Being totally clueless about SSL. CAS is designed so you can hack SSL out of it. But any self-respecting multi-domain SSO architecture needs to feature SSL because it is fundamentally important that client applications are not "spoofed" into thinking that the user has already logged in. For this, we need trust established between server and client. To implement this, we use a technique that is analogous to most daily business transactions. When you cash a check or use a credit card, you are sometimes asked to show your driver license to prove you are who you say you are. In this case, the merchant and you trust the Department of Motor Vehicles (DMV), which is a mutually acceptable independent "Certification Authority". Browsers establish (and enforce) this type of mutually trustworthy transactions through the Secure Socket Layer (SSL) protocol. Besides digital signatures certifying servers and clients, SSL gives you data confidentiality through encryption and data integrity through message-specific codes...good stuff. For applications that are deployed within your development environments, you can "self-certify" this SSL transaction. However, for external facing applications, when you are in production dealing with third parties outside your own LAN, SSL must be certified by a trusted third party like Verisign, Thawte. Any more discussion of SSL is out of scope of this wiki...which will just get your demo going. But please plan to do the needed research into SSL and also ensure that your company can support this down the road (it costs a few hundred dollars per certificate, plus you need to be legit business with a real address, etc...).
Ambiguous JRE location. You may have installed Java SDK and Tomcat long, long time ago and are unclear which JRE your tomcat points to anymore, for instance. Or you may already be doing SSL. It is VERY critical you know your tomcat installation (crystal clear). Otherwise, the best course of action is to install from scratch for this demo. Proceed at your own risk if you are unclear on this and skip the JDK and tomcat installs in the wiki below. CAS is going to be a critical server component in your enterprise anyway. It needs a little more respect than a completely self-contained JSP application that is plopped into an existing tomcat as a war. CAS clients will have that luxury, but certainly not the server, which brings me to...
What is SOA? I don't think you need to be an Service Oriented Architecture (SOA) expert to use CAS but you need to have some idea. Just installing a CAS sever is not going to get the job done. You need to configure your client application somewhat to "consume" the SSO service provided by the CAS server. This is basic to distributed, loosely coupled interactions that characterize SOA. For a tomcat client application of CAS, this just means two things: add a few lines to your web.xml, drop a few jars files into your WEB-INF/lib and reload. It does not get any simpler than that. But it does mean that your old login page, if you had one, perhaps will be retired. Even more deeply, it means that your applications will have less information about the user than before. If you didn't care ok. But note that you will need to ensure that any roles, privileges etc are taken care of within client application. To mix authentication and authorization is a bad idea. CAS is designed to serve many masters and cannot possibly please everyone with the same exact code. I will show you below how you can get the SSO login username within a tomcat client application, but that it is all you will get out-of-the-box from CAS. Your client application will have to take it from there, as to what the user can or cannot see. And, remember that CAS does not do a tomcat login for you...it is within CAS that a user session is maintained, not the local application container. Even if you did not comprehend all that SOA, you may proceed for now, but I guarantee you will run up against that wall: "How do I know who logged in?". Answer: CAS supports that out-of-the-box. "How do I control what the user can see?". Answer: CAS does not (should not) do that for you...it just lets user in the door (or slams it shut). Your application will not (and should not) have even the password of the user to "play with". Client applications need to independently figure out roles/privileges. Unless, of course, you are willing to create rather exotic extensions or configurations of CAS itself. Note that CAS is open source, so you can certainly do whatever you want with it to suit your needs. Or, you may look into frameworks that play well with CAS like Acegi Security. But we are getting way ahead of ourselves.
With that preamble, let's begin...
Stepwise Instructions
Basically, recommend starting fresh with (instruction are for a Windows XP professional computers) with no JDK/JRE or Tomcat. Using Microsoft Internet Explorer Version 7.0.5730.11 to verify SSL etc.
Step 1: Install JDK Version
download jdk-1_5_0_11-windows-i586-p.exe from java.sun.com
conduct a typical installation, doing next, next, next
set JAVA_HOME system environment variable to, well, java home... C:\Program Files\Java\jdk1.5.0_11
Step 2: Used keytool to self-author a server certificate for DEMO
Reference: http://www.ja-sig.org/wiki/display/CAS/Solving+SSL+issues
Entire Command Prompt Dialog is below...
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\ukari>cd \program*
The filename, directory name, or volume label syntax is incorrect.
C:\Program Files>cd java
C:\Program Files\Java>cd jdk*
C:\Program Files\Java\jdk1.5.0_11>cd bin
C:\Program Files\Java\jdk1.5.0_11\bin>keytool -genkey -alias tomcat -keypass changeit -keyalg RSA
Enter keystore password: changeit
What is your first and last name?
[Unknown]: compA
What is the name of your organizational unit?
[Unknown]: Information Systems
What is the name of your organization?
[Unknown]: Pacific Disaster Center
What is the name of your City or Locality?
[Unknown]: Kihei
What is the name of your State or Province?
[Unknown]: HI
What is the two-letter country code for this unit?
[Unknown]: US
Is CN=localhost, OU=Information Systems, O=Pacific Disaster Center, L=Kihei, ST=HI, C=US correct?
[no]: yes
C:\Program Files\Java\jdk1.5.0_11\bin>keytool -export -alias tomcat -keypass changeit -file server.crt
Enter keystore password: changeit
Certificate stored in file <server.crt>
C:\Program Files\Java\jdk1.5.0_11\bin>keytool -import -file server.crt -keypass changeit -keystore ..\jre\lib\security\cacerts
Enter keystore password: changeit
Owner: CN=localhost, OU=Information Systems, O=Pacific Disaster Center, L=Kihei, ST=HI, C=US
Issuer: CN=localhost, OU=Information Systems, O=Pacific Disaster Center, L=Kihei, ST=HI, C=US
Serial number: 462030d8
Valid from: Fri Apr 13 15:39:36 HST 2007 until: Thu Jul 12 15:39:36 HST 2007
Certificate fingerprints:
MD5: CC:3B:FB:FB:AE:12:AD:FB:3E:D 5:98:CB:2E:3B:0A:AD
SHA1: A1:16:80:68:39:C7:58:EA:2F:48:59:AA:1D:73:5F:56:78:CE:A4:CE
Trust this certificate? [no]: yes
Certificate was added to keystore
C:\Program Files\Java\jdk1.5.0_11\bin>
CAS Server Name
In the above dialog, it is critical that you enter the CAS server name as the answer (compA) to the following question:
What is your first and last name?
[Unknown]: compA
At this stage we have a .keystore file created in C:\Documents and Settings\<user> and the %JAVA_HOME%\jre\lib\security\cacerts file with the corresponding certificate.
Step 3: Install Tomcat
Selected the Windows Installer version at http://tomcat.apache.org/download-55.cgi#5.5.23
When prompted for directory, changed it to C:\tomcat5.5.23
When prompted for applications, I added all examples, webapps etc. (useful for testing CAS)
When prompted for JRE, changed default to %JAVA_HOME%/jre (IMPORTANT: this should be home of new cacerts from step 2)
Clicked finish and verified tomcat running as a service and also by doing http://localhost:8080
Ensure that logs look very clean as well.
Set environment variable %CATALINA_HOME% as C:\tomcat5.5.23
Tomcat JRE Home
In the above dialog, it is critical in that you select the JRE home where you put the cacerts file in step 2. In this case, please note that we are using %JAVA_HOME%/jre
Step 4: Configure Tomcat server.xml
uncomment connector element for port 8443 (SSL)
add the parameters for keystoreFile, keystorePass, truststoreFile as shown below
bounce tomcat
<!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
<Connector port="8443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="C:/Documents and Settings/ukari/.keystore"
keystorePass="changeit"
truststoreFile="C:/Program Files/Java/jdk1.5.0_11/jre/lib/security/cacerts" />
Step 5: CASify HelloWorld Servlet
http://www.ja-sig.org/wiki/display/CASC/Using+CASFilter
[http://www.ja-sig.org/products/cas/client/javaclient/index.html]
verify that http://compA:8080/servlets-examples/servlet/HelloWorldExample works.
add the following to web.xml of the servlets-examples context.
<filter>
<filter-name>CAS Filter</filter-name>
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
<param-value>https://compA:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://compA:8443/cas/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>compA:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlet/HelloWorldExample</url-pattern>
</filter-mapping>
Step 6: Drop CAS Client jar into the servlets-examples context
URL: http://www.ibiblio.org/maven/cas/jars/
create the lib directory under servlets-examples/WEB-INF
download that casclient-2.1.1.zip into C:\Tomcat5.5.23\webapps\servlets-examples\WEB-INF\lib
RENAME the zip file to jar file.
Note that for Tomcat 6 you must also include commons-logging in the lib folder: http://www.ibiblio.org/maven/commons-logging/jars/commons-logging-1.0.4.jar
Step 7: Download and Deploy CAS
URL: http://www.ja-sig.org/products/cas/downloads/index.html
download the cas-server-3.0.7.zip file.
extract it all to c:\cas-server-3.0.7 directory.
copy cas.war from C:\cas-server-3.0.7\cas-server-3.0.7\target to C:\Tomcat5.5.23\webapps
(this deploys cas if tomcat is running...but just to be sure...step
Step 8. Clean start
stop tomcat, clear all logs, start tomcat
examine logs
stdout_20070413.log (looks "normal"):
2007-04-13 16:32:02,082 INFO [org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler] \- <No PasswordEncoder set. Using default: org.jasig.cas.authentication.handler.PlainTextPasswordEncoder>
2007-04-13 16:32:02,082 INFO [org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler] \- <No Class to Support set. Using default: org.jasig.cas.authentication.principal.UsernamePasswordCredentials>
2007-04-13 16:32:02,082 WARN [org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler] \- <org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler is only to be used in a testing environment. NEVER enable this in a production environment.>
2007-04-13 16:32:02,129 INFO [org.jasig.cas.ticket.proxy.support.Cas20ProxyHandler] \- <No UniqueTicketIdGenerator specified for org.jasig.cas.ticket.proxy.support.Cas20ProxyHandler. Using org.jasig.cas.util.DefaultUniqueTicketIdGenerator>
2007-04-13 16:32:04,316 INFO [org.jasig.cas.web.ServiceValidateController] \- <No successView specified. Using default of casServiceSuccessView>
2007-04-13 16:32:04,316 INFO [org.jasig.cas.web.ServiceValidateController] \- <No failureView specified. Using default of casServiceFailureView>
2007-04-13 16:32:04,363 INFO [org.jasig.cas.web.ServiceValidateController] \- <No authentication specification class set. Defaulting to org.jasig.cas.validation.Cas20ProtocolValidationSpecification>
2007-04-13 16:32:04,363 INFO [org.jasig.cas.web.ServiceValidateController] \- <No successView specified. Using default of casServiceSuccessView>
2007-04-13 16:32:04,363 INFO [org.jasig.cas.web.ServiceValidateController] \- <No failureView specified. Using default of casServiceFailureView>
2007-04-13 16:32:04,473 INFO [org.jasig.cas.web.flow.AuthenticationViaFormAction] \- <FormObjectClass not set. Using default class of org.jasig.cas.authentication.principal.UsernamePasswordCredentials with formObjectName credentials and validator org.jasig.cas.validation.UsernamePasswordCredentialsValidator.>
2007-04-13 16:32:22,223 INFO [org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner] \- <Starting cleaning of expired tickets from ticket registry at [Fri Apr 13 16:32:22 HST 2007]>
2007-04-13 16:32:22,223 INFO [org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner] \- <0 found to be removed. Removing now.>
2007-04-13 16:32:22,223 INFO [org.jasig.cas.ticket.registry.support.DefaultTicketRegistryCleaner] \- <Finished cleaning of expired tickets from ticket registry at [Fri Apr 13 16:32:22 HST 2007]>
catalina.2007-04-13.log (looks "normal"):
Apr 13, 2007 4:31:56 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Tomcat5.5.23\bin;.;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\ATI Technologies\ATI Control Panel;C:\Program Files\Common Files\Adobe\AGL
Apr 13, 2007 4:31:57 PM org.apache.coyote.http11.Http11BaseProtocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Apr 13, 2007 4:31:58 PM org.apache.coyote.http11.Http11BaseProtocol init
INFO: Initializing Coyote HTTP/1.1 on http-8443
Apr 13, 2007 4:31:58 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 2859 ms
Apr 13, 2007 4:31:58 PM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Apr 13, 2007 4:31:58 PM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/5.5.23
Apr 13, 2007 4:31:58 PM org.apache.catalina.core.StandardHost start
INFO: XML validation disabled
Apr 13, 2007 4:32:00 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive cas.war
Apr 13, 2007 4:32:06 PM org.apache.coyote.http11.Http11BaseProtocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Apr 13, 2007 4:32:07 PM org.apache.coyote.http11.Http11BaseProtocol start
INFO: Starting Coyote HTTP/1.1 on http-8443
Apr 13, 2007 4:32:07 PM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Apr 13, 2007 4:32:07 PM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/47 config=null
Apr 13, 2007 4:32:07 PM org.apache.catalina.storeconfig.StoreLoader load
INFO: Find registry server-registry.xml at classpath resource
Apr 13, 2007 4:32:07 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 8891 ms
localhost.2007-04-13.log (looks "normal"):
Apr 13, 2007 4:32:04 PM org.apache.catalina.core.ApplicationContext log
INFO: org.apache.webapp.balancer.BalancerFilter: init(): ruleChain: \[org.apache.webapp.balancer.RuleChain: [org.apache.webapp.balancer.rules.URLStringMatchRule: Target string: News / Redirect URL: http://www.cnn.com], [org.apache.webapp.balancer.rules.RequestParameterRule: Target param name: paramName / Target param value: paramValue / Redirect URL: http://www.yahoo.com], [org.apache.webapp.balancer.rules.AcceptEverythingRule: Redirect URL: http://jakarta.apache.org]\]
Apr 13, 2007 4:32:05 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Apr 13, 2007 4:32:05 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Apr 13, 2007 4:32:05 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Apr 13, 2007 4:32:05 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
All other log files stderr, admin, host-manager, jakarta_service, manager are of size 0K. Checked stderr just to make sure...
Step 9. Try It
Use fresh browser session to access http://compA:8080/servlets-examples/servlet/HelloWorldExample
Get past all browser alerts/warnings to CAS login page
Log in as uday/uday (or any username=password string)
Again see all sorts of alerts/warnings
See Hello World...success.
Logs
stdout_20070413.log (three new records):
2007-04-13 16:39:01,238 INFO [org.jasig.cas.web.flow.AutomaticCookiePathSetterAction] \- <Setting ContextPath for cookies to: /cas>
2007-04-13 16:39:18,271 INFO [org.jasig.cas.authentication.AuthenticationManagerImpl] \- <AuthenticationHandler: org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler successfully authenticated the user which provided the following credentials: uday>
2007-04-13 16:39:18,286 INFO [org.jasig.cas.CentralAuthenticationServiceImpl] \- <Granted service ticket [ST-2-V03EdNba1e3cMxeoEbEHwXfoefftIeeRxuO-20] for service [http://compA:8080/servlets-examples/servlet/HelloWorldExample] for user [uday]>
localhost.2007-04-13.log (new records):
Apr 13, 2007 4:38:51 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: sessionCreated('6ED4CFE9A5D7BA592372A3E67DF7D6E8')
Apr 13, 2007 4:38:51 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: attributeAdded('6ED4CFE9A5D7BA592372A3E67DF7D6E8', 'edu.yale.its.tp.cas.client.filter.didGateway', 'true')
Apr 13, 2007 4:38:51 PM org.apache.catalina.core.ApplicationContext log
INFO: InvokerFilter(ApplicationFilterConfig[name=Path Mapped Filter, filterClass=filters.ExampleFilter]): 31 milliseconds
Apr 13, 2007 4:39:19 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: attributeAdded('6ED4CFE9A5D7BA592372A3E67DF7D6E8', 'edu.yale.its.tp.cas.client.filter.user', 'uday')
Apr 13, 2007 4:39:19 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: attributeAdded('6ED4CFE9A5D7BA592372A3E67DF7D6E8', 'edu.yale.its.tp.cas.client.filter.receipt', '\[edu.yale.its.tp.cas.client.CASReceipt userName=[uday] casValidateUrl=[https://compA:8443/cas/serviceValidate] proxyCallbackUrl=[null] pgtIou=[null] casValidateUrl=[https://compA:8443/cas/serviceValidate] proxyList=\[\[\]\]\]')
Apr 13, 2007 4:39:19 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: attributeRemoved('6ED4CFE9A5D7BA592372A3E67DF7D6E8', 'edu.yale.its.tp.cas.client.filter.didGateway', 'true')
Apr 13, 2007 4:39:19 PM org.apache.catalina.core.ApplicationContext log
INFO: InvokerFilter(ApplicationFilterConfig[name=Path Mapped Filter, filterClass=filters.ExampleFilter]): 860 milliseconds
All other logs unchanged. Done (Success). Well sorta. This is the absolute minimal "proof-of-life" with Yale CAs. Still need to CAS-ify some other application and see if it works between two applications on separate machines...which leads us to...
Step 10: Setup up distinct domain
Repeat repeat Steps 1 thru 4 above for compB. Just do it, dont worry about creating a server certificate etc...Tomcat seems to like a keystore. So just do it.
Step 11: CAS-ify client on second domain slightly differently
In step 5, modify the direction above to add compB as the client-host as follows (obviously, leave the rest of it alone).
Server Name Specification
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>compB:8080</param-value>
</init-param>
Though not needed for this demo, I promised to show you how you may get the user. This is how. Add the following right after the server name specification as a child of the <filter> element and as a sibling of the above init-param element for server name. This entry will allow you to access the login user name as String username = request.getRemoteUser(); within any of the secured jsp. Try it!
Config for getting user name in request
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.wrapRequest</param-name>
<param-value>true</param-value>
</init-param>
Another useful tip is that you may secure as many resources as you wish within your context by simply adding the following:
Adding multiple secured resources
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlet/RequestHeaderExample</url-pattern>
</filter-mapping>
The final compB web.xml modifications should look as follows:
<filter>
<filter-name>CAS Filter</filter-name>
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
<param-value>https://compA:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://compA:8443/cas/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>compB:8080</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.wrapRequest</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlet/HelloWorldExample</url-pattern>
</filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/servlet/RequestHeaderExample</url-pattern>
</filter-mapping>
Step 12: Drop CAS Client jar into the servlets-examples context
Identical to Step 6, but for compB.
Step 13: Establish trust with CAS SSO Server
Ref: http://blogs.sun.com/andreas/entry/no_more_unable_to_find
Here is the most elegant way to do it, I think.
In compB, simply copy the cacerts to cacerts.old (to save it just in case)
run java InstallCert compA:8443 (i.e. provide the argument "compA:8443" to the executable "InstallCert")
(adapted source code for InstallCert.java from Sun blog by Andreas Sterbenz is shown below)
Answer 1 to the prompt
This will add compA into trust store of compB (while neatly obviating the problem discussed in the Sun blog referenced above).
InstallCert.java - adapted from Sun Microsystems blog by Andreas Sterbenz
/*
* @(#)InstallCert.java 1.1 06/10/09
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
import java.io.*;
import java.net.URL;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
public class InstallCert {
public static void main(String[] args) throws Exception {
String host;
int port;
char[] passphrase;
if ((args.length == 1) || (args.length == 2)) {
String[] c = args[0].split(":");
host = c[0];
port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
String p = (args.length == 1) ? "changeit" : args[1];
passphrase = p.toCharArray();
} else {
System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
return;
}
File file = new File("jssecacerts");
if (file.isFile() == false) {
char SEP = File.separatorChar;
File dir = new File(System.getProperty("java.home") + SEP
+ "lib" + SEP + "security");
file = new File(dir, "jssecacerts");
if (file.isFile() == false) {
file = new File(dir, "cacerts");
}
}
System.out.println("Loading KeyStore " + file + "...");
InputStream in = new FileInputStream(file);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(in, passphrase);
in.close();
SSLContext context = SSLContext.getInstance("TLS");
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
context.init(null, new TrustManager[] {tm}, null);
SSLSocketFactory factory = context.getSocketFactory();
System.out.println("Opening connection to " + host + ":" + port + "...");
SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
socket.setSoTimeout(10000);
try {
System.out.println("Starting SSL handshake...");
socket.startHandshake();
socket.close();
System.out.println();
System.out.println("No errors, certificate is already trusted");
} catch (SSLException e) {
System.out.println();
e.printStackTrace(System.out);
}
X509Certificate[] chain = tm.chain;
if (chain == null) {
System.out.println("Could not obtain server certificate chain");
return;
}
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
System.out.println();
System.out.println("Server sent " + chain.length + " certificate(s):");
System.out.println();
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
MessageDigest md5 = MessageDigest.getInstance("MD5");
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = chain[i];
System.out.println
(" " + (i + 1) + " Subject " + cert.getSubjectDN());
System.out.println(" Issuer " + cert.getIssuerDN());
sha1.update(cert.getEncoded());
System.out.println(" sha1 " + toHexString(sha1.digest()));
md5.update(cert.getEncoded());
System.out.println(" md5 " + toHexString(md5.digest()));
System.out.println();
}
System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
String line = reader.readLine().trim();
int k;
try {
k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
} catch (NumberFormatException e) {
System.out.println("KeyStore not changed");
return;
}
X509Certificate cert = chain[k];
String alias = host + "-" + (k + 1);
ks.setCertificateEntry(alias, cert);
OutputStream out = new FileOutputStream(file);
ks.store(out, passphrase);
out.close();
System.out.println();
System.out.println(cert);
System.out.println();
System.out.println
("Added certificate to keystore 'cacerts' using alias '"
+ alias + "'");
}
private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
private static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 3);
for (int b : bytes) {
b &= 0xff;
sb.append(HEXDIGITS[b >> 4]);
sb.append(HEXDIGITS[b & 15]);
sb.append(' ');
}
return sb.toString();
}
private static class SavingTrustManager implements X509TrustManager {
private final X509TrustManager tm;
private X509Certificate[] chain;
SavingTrustManager(X509TrustManager tm) {
this.tm = tm;
}
public X509Certificate[] getAcceptedIssuers() {
throw new UnsupportedOperationException();
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
throw new UnsupportedOperationException();
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
this.chain = chain;
tm.checkServerTrusted(chain, authType);
}
}
}
Step 14: Test
Clean logs, restart tomcat on compB.
Repeat Step 9.
Change compA to compB on the URL.
You should not be challenged to login (QED)
Restart tomcat and try again, you should have to login to compB
And, not to compA
Congratulations.
发表评论
-
ssh框架加入atomikos分布式事务管理
2015-01-06 18:48 1470一、概念 分布式事务分布式事务是指事务 ... -
Spring 动态切换数据源
2014-05-09 14:30 3640一、开篇 这里整合分别采用了Hibernate和MyB ... -
Spring切入点表达式常用写法
2014-05-09 14:25 818自从使用AspectJ风格切面配置,使得Spring的切面配 ... -
Spring中线程池的应用
2014-03-24 11:03 899多线程并发处理起来通常比较麻烦,如果你使用spring容器来 ... -
Spring线程池开发实战
2014-03-24 11:02 756本文提供了三个Spring多线程开发的例子,由浅入深,由于例 ... -
JSch - Java实现的SFTP(文件上传详解篇)
2013-11-21 09:36 901JSch是Java Secure Channel的缩写。J ... -
JAVA线程池ThreadPoolExecutor
2013-07-17 14:45 899java.util.concurrent.ThreadPoo ... -
log4j.properties 使用说明
2013-05-29 10:54 812一、Log4j简介Log4j有三个主要的组件:Logger ... -
eclipse安装反编译插件(附jad下载)
2012-12-12 10:45 826一、eclipse反编译插件Jadclipse jadclip ... -
web.xml 配置404和500错误的自定义页面
2012-12-07 11:47 816web.xml <error-page>< ... -
java内存溢出
2012-06-28 18:57 871一、常见的Java内存溢出 ... -
List Set Map区别
2012-12-25 17:54 918List有序key和value都能重 ... -
Java 自定义Annotation(元数据、注解)
2011-08-05 11:50 1910Annotation在java的世界正铺天盖地展开,有空写这一 ... -
LOG4J properties 配置文件
2011-06-29 16:31 1174一、参数意义说明1、输出级别的种类 ERROR、 ... -
servlet输出一个文件
2010-11-10 18:33 1170String fileName= file.getName() ... -
关于RSS、RDF、ATOM和Feed
2010-11-02 09:48 1226RSS被不同的技术团体做不同的解释,分别有 Rich Site ... -
正确理解Traceback的含义
2010-11-02 09:44 1010Traceback是Blog的一个重要 ... -
关于Serializable的serialVersionUID
2010-10-26 09:10 1758众所周知,当某class实现了Serializable接口 ... -
获得CLASSPATH之外路径的方法
2010-10-14 10:37 961URL base = this.getClass().getR ... -
操作properties文件
2010-10-14 10:30 807发个例子大家自己看哈.package control; im ...
相关推荐
1. 下载和安装:你可以从官方仓库下载CAS服务器的最新版本,然后根据提供的指南进行安装。 2. 配置服务器:修改服务器的配置文件,比如`cas.properties`,设置数据库连接、认证策略、邮件通知等参数。 3. 集成认证...
- 使用提供的CAS Java实例进行测试,确保配置正确无误,可以通过模拟不同场景,如正常登录、无效凭证、单点登出等,来检查CAS功能是否正常运行。 - 注意检查日志输出,这有助于识别和解决可能出现的问题。 总之,...
- `apache-tomcat-cas`:这是用于部署CAS服务器的Tomcat实例,CAS服务器在这里运行并提供认证服务。 - `apache-tomcat-1` 和 `apache-tomcat-2`:这两个是部署应用系统的Tomcat实例,比如`casapp1`和`casapp2`,它们...
本实例主要探讨如何将 Apache Shiro 与 CAS 整合,实现一个统一的身份验证系统。下面将详细介绍整合过程中的关键步骤和涉及的知识点。 1. **安装和配置 CAS 服务器** - 首先,你需要下载并部署 CAS 服务器。CAS ...
**Spring Security集成CAS客户端实例详解** 在Web应用中,安全是至关重要的,Spring Security和CAS(Central Authentication Service)是两种广泛使用的安全框架。本实例旨在展示如何将Spring Security与CAS结合,...
标题 "cas 系统实例 服务端配置(一)" 提到的是 CAS(Central Authentication Service)系统的一个服务端配置教程。CAS 是一个开源的身份验证框架,主要用于实现单一登录(Single Sign-On, SSO)。在本教程中,我们...
标题和描述均提到了“Acegi Security整合CAS实例”,这涉及到Spring Framework下的Acegi Security模块与CAS(Central Authentication Service)的集成。Acegi Security是Spring框架的一个子项目,旨在为应用提供安全...
【标题】"CAS官方提供的例子改造"涉及到的核心知识点是单点登录(Single Sign-On, SSO)系统,特别是关于CAS(Central Authentication Service)的实践应用。CAS是一种开放源码的SSO协议,它允许用户通过一个认证...
cas实例,实现身份验证和跳转,
SSO实例安装和配置指南PDF版 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。
本文将深入探讨CAS单点登录实例及其相关知识点。 首先,单点登录(Single Sign-On,SSO)是一种身份验证机制,使得用户在一个应用系统中登录后,无需再次输入认证信息即可访问其他关联的应用系统。CAS作为开源的SSO...
- 部署CAS服务器需要下载官方发布的CAS服务端war包,并将其部署到Servlet容器中。 - 配置服务器包括设置数据库连接(存储用户信息)、SSL证书(确保通信安全)以及定制化登录页面等。 2. **CAS客户端集成** - ...
标题 "cas+shiro+spring实例" 涉及到的是一个集成CAS(Central Authentication Service)和Apache Shiro的Spring应用程序实例。这个实例是专为初学者设计的,旨在帮助他们理解和实现基于CAS的单点登录(Single Sign-...
CAS(Central Authentication Service)是...通过这个实例,你可以深入了解SSO的工作原理,学习如何配置和部署CAS服务,以及如何在自己的应用中实现CAS客户端,这对于提升企业级应用的安全性和用户体验有着重要的作用。
spring+springmvc+shiro+cas单点登录实例 springmvc+spring+shiro+cas单点登录实例 加入了登录验证码认证,修改了下首页样式,不过样式没有弄好,很丑的,有空自己再弄下 说明:cas-server是单点登录服务端,用的是...
在这个实例中,我们关注的是CAS 3.4.7版本,这是一个相对较老但仍然有其应用价值的版本。在CAS 3.4.7中,我们将学习如何配置它来连接到Access数据库,这在一些小型或内部网络环境中可能是首选的数据库解决方案。 ...
### CAS单点登录实例详细步骤解析 #### 一、引言 CAS(Central Authentication Service)是一种开放源码的单点登录(SSO)协议,它允许用户在一个应用中登录后,无需再次输入用户名和密码就能访问同一域内的其它...
通过"SSO之CAS单点登录实例演示",我们可以实践这些步骤,了解如何设置和运行一个基本的CAS环境,进一步理解SSO的工作原理和实际应用。这个实例将帮助我们更好地掌握如何为自己的应用实现SSO功能,提升系统的安全性...
本资源“落雨博客基于CAS框架的单点登录技术讲解(ppt+code实例+doc)配套资料”提供了一个全面的学习材料,包括PPT演示、代码实例和文档,帮助你深入理解并掌握如何在实际项目中运用CAS进行单点登录的实现。...