Single Sign-on, or SSO, is one of the most popular solutions for enterprise business integration, and SSO enables users to access all trusted applications in multiple application systems with only one login. CAS (central authentication Service) is a good single sign-on framework for WEB applications, this article describes the principles, protocols, configuration and use of CAs in Tomcat, for CAs Getting Started with lightweight single sign-on solutions can be a guide for readers.
CAS Introduction
CAS is an open source project launched by Yale University, designed to provide a reliable single sign-on approach to WEB applications, and CAS became a Ja-sig project in December 2004. CAS has the following characteristics:
Open source enterprise-level Single sign-on solution. CAS Server is a Web app that needs to be deployed independently. CAS client supports a very wide range of clients (this refers to individual WEB applications in a single sign-on system), including Java,. Net, PHP, Perl, Apache, Uportal, Ruby, and more.
CAS Principles and protocols
Structurally, CAs consists of two parts: CAs Server and CAS Client. CAS server needs to be deployed independently, primarily responsible for authenticating users; The CAS client handles access requests to client-protected resources and redirects to CAS server when it needs to log on. Figure 1 is the most basic protocol process for CAS:
Figure 1. CAS Foundation Protocol
The CAS client is deployed together with protected client applications to protect protected resources in a Filter manner. For each WEB request that accesses a protected resource, CAS Client parses the request for a Service Ticket in the Http request, and if not, redirects the request to the specified CAS Server login address and passes the Serv Ice (that is, the address of the destination resource to be accessed) so that the login succeeds and turns back to that address. The user enters the authentication information in the 3rd step, if the login succeeds, CAS Server randomly generates a fairly long, unique, non-counterfeit Service Ticket, and caches it for future verification, then the system automatically redirects to the address of the Service and sets a Ticket granted Cookie (TGC), CAs Client is properly identified with CAs Server in 5th, 6 steps after receiving service and newly generated Ticket to ensure the legality of service Ticket.
In this protocol, all interactions with CAS are SSL-based, ensuring the security of ST and TGC. There are 2 redirects during the protocol work process, but the process of Ticket authentication between CAs Client and CAS Server is transparent to the user.
In addition, the CAS protocol provides proxy mode to accommodate more advanced and complex application scenarios, with reference to the relevant documents on the CAS official website.
Preparatory work
The examples in this article are explained in tomcat5.5, for example:
To the CAS official website, download CAs Server and Client, respectively:
Deploying CAS Server
CAS server is a Java-based implementation of a service that is deployed separately on a servlet2.3-compatible Web server with a Java Web application, and because the interaction between Client and CAS server uses H TTPS protocol, the server that deploys CAS server also needs to support the SSL protocol. When the SSL configuration succeeds, the CAS server is deployed on the server just like a normal Web app, but before you can actually use it, you need to extend the authentication user's interface.
Deploying a full CAS Server on Tomcat is primarily based on the following steps:
If you want Tomcat to support HTTPS, the main task is to configure the SSL protocol, and the configuration process and configuration method can refer to the related documentation for Tomcat. However, in the process of generating the certificate, there will be a need to use the host name, CAS does not recommend using an IP address, but to use the machine name or domain name.
Deploying CAS Server
CAS Server is a WEB app package that unlocks the previously downloaded cas-server-3.1.1-release.zip, copies the Cas-server-webapp-3.1.1.war to the Tomcat WebApps directory, and renames For Cas.war. Because the HTTPS protocol for Tomcat has been configured earlier, you can restart Tomcat and then access: Https://localhost:8443/cas, if the normal CAS login page appears, the CAS Server has been deployed successfully.
Although CAS server has been deployed successfully, this is only a default implementation, and when actually used, it needs to be extended and customized according to the actual situation, most notably the extended authentication (authentication) interface and the CAS server interface.
Extended Authentication Interface
CAS Server is responsible for completing the authentication work for the user, which processes the user credentials (Credentials) information at logon, and the user name/password pair is the most common credential information. CAS server may need to retrieve a user account information to the database, may also retrieve the user name/password in the XML file, and possibly through LDAP Server acquisition, in this case, the CAS provides a flexible but unified interface and implementation of a separate way, the actual use of CAs Which method of authentication is separated from the basic protocol of CAS, the user can customize and expand according to the authentication interface.
CAS provides extended authentication at the core of the Authenticationhandler interface, which is defined in Listing 1:
Public interface Authenticationhandler {/** * Method to determine if the credentials supplied is valid. * @param cred Entials the credentials to validate. * @return True if valid, return False otherwise. * @throws authenticationexception an authenticationexception can contain * Details on why a particular authentication R Equest failed. */Boolean Authenticate (Credentials Credentials) throws authenticationexception; /** * Method to check if the handler knows what to handle the credentials * provided. It May is a simple check on the Credentials class or something * more complicated such as scanning the information contain Ed in the * Credentials object. * @param credentials the credentials to check. * @return True if the handler supports the Credentials, False othewrise. */Boolean Supports (Credentials Credentials); }
The interface defines 2 methods that need to be implemented, and the Supports () method is used to check whether the given credentials that contains the authentication information is supported by the current Authenticationhandler, while the Authenticate () The method serves as the task of verifying the authentication information, which is also the main method that needs to be extended, interacts with the media that stores the legitimate authentication information according to the situation, returns a Boolean type value, True indicates that the validation passed, and False indicates that the validation failed.
CAS3 also provides some abstract implementations of the Authenticationhandler interface, for example, you might need to perform some other action before and after the authenticate () method, so you can extend your own authentication class from the abstract class in Listing 2:
Public abstract class Abstractpreandpostprocessingauthenticationhandler implements authenticatehandler{ Protected log log = Logfactory.getlog (This.getclass ()); Protected Boolean preauthenticate (final Credentials Credentials) {return true;} protected Boolean postauthenticate (FINA L Credentials Credentials, final Boolean authenticated) {return authenticated;} public final Boolean authenticate (final Credentials Credentials) throws Authenticationexception {if (!preauthenticate (Credentials)) {return false;} final Boole An authenticated = Doauthentication (credentials); Return postauthenticate (credentials, authenticated); } protected Abstract Boolean doauthentication (final Credentials Credentials) throws authenticationexception; }
The Abstractpreandpostprocessingauthenticationhandler class defines the PreAuthenticate () method and the Postauthenticate () method, and the actual certification work is handed over to the Doauthentication () method to execute. Therefore, if you need to perform some additional operations before and after authentication, you can expand the PreAuthenticate () and Ppstauthenticate () methods separately, and doauthentication () instead of authenticate () becomes a method that the subclass must implement.
As a result of the actual application, the most common is the user name and password authentication, CAS3 provides the implementation of this approach, as shown in Listing 3:
Public abstract class Abstractusernamepasswordauthenticationhandler extends abstractpreandpostprocessingauthenticationhandler{protected Final Boolean doauthentication (final Credentials Credentials) throws Authenticationexception {return authenticateusernamepasswordinternal ( Usernamepasswordcredentials) credentials); } protected Abstract Boolean authenticateusernamepasswordinternal (final usernamepasswordcredentials credentials) Throws Authenticationexception; Protected final Passwordencoder Getpasswordencoder () {return this.passwordencoder;} public final void Setpasswordencode R (Final Passwordencoder passwordencoder) {this.passwordencoder = Passwordencoder;} ...}
The authentication method based on the user name password can be directly extended from Abstractusernamepasswordauthenticationhandler, and the specific operation of verifying the user name password is implemented by Authenticateusernamepasswordinternal () method is achieved, in addition, usually the password will be encrypted, the Setpasswordencoder () method is used to specify the appropriate encryption device.
As can be seen from the above list, the Doauthentication () method parameter is the Credentials type, which is an interface containing user authentication information, for the user name password type authentication information, you can directly use Usernamepasswordcredentials, if you need to extend other types of authentication information, you need to implement the credentials interface, and implement the corresponding Credentialstoprincipalresolver interface, Its specific methods can be used for reference usernamepasswordcredentials and Usernamepasswordcredentialstoprincipalresolver.
The user's authentication information is usually saved in the database, so this article chooses this situation to introduce. After unlocking the previously downloaded Cas-server-3.1.1-release.zip package, the package Cas-server-support-jdbc-3.1.1.jar can be found under the Modules directory, which provides a JDBC The default implementation of connection database validation, based on the support of this package, we only need to do some configuration work to achieve JDBC authentication.
The JDBC authentication method supports a variety of databases, DB2, Oracle, MYSQL, Microsoft SQL Server, and so on, with DB2 as an example. and assume DB2 database name: castest, database login user name: db2user, database login password: db2password, the User Information table is: usertable, the table contains the user name and password two data items are userName and password respectively.
Open the file%catalina_home%/webapps/cas/web-inf/deployerconfigcontext.xml, add a new bean tag, and for DB2, the contents are shown in Listing 4:
Listing 4. Configure DataStore
<bean > <property > <value>com.ibm.db2.jcc.DB2Driver</value> </property> <property > <value>jdbc:db2://9.125.65.134:50000/CASTest</value> </property> <property > <value >db2user</value> </property> <property > <value>db2password</value> </property > </bean>
Where the id attribute is the identity of the DataStore, the configuration Authenticationhandler is referenced later, and you need to provide the database driver, connection address, database login user name, and login password that are required for DataStore.
In the Cas-server-support-jdbc-3.1.1.jar package, 3 JDBC-based authenticationhandler are provided, respectively, for Bindmodesearchdatabaseauthenticationhandler, Querydatabaseauthenticationhandler, Searchmodesearchdatabaseauthenticationhandler. Where Bindmodesearchdatabaseauthenticationhandler is to use the given username and password to establish a database connection, based on the success of the connection established to determine the success of the verification ; Querydatabaseauthenticationhandler by configuring a SQL statement to isolate the password and match the given password; searchmodesearchdatabaseauthenticationhandler Constructs a query statement to validate by configuring the table, User Name field, and password fields that hold user authentication information.
Which authenticationhandler to use, which needs to be set in Deployerconfigcontext.xml, by default, CAS uses a simple Username=password Authenticationhandler, the following line can be found in the file: <bean >authenticationhandler "/> we can comment it out and replace it with the one we want. Authenticationhandler, for example, using Querydatabaseauthenticationhandler or Searchmodesearchdatabaseauthenticationhandler You can select the configuration for listing 5 or listing 6, respectively.
<bean > <property ref= "casdatasource"/> <property value= "Select password from usertable where lower (user Name) = lower (?) "/> </bean>
<bean abstract= "false" singleton= "true" lazy-init= "Default" autowire= "Default" dependency-check= "Default" > <property > <value>userTable</value> </property> <property > <value>userName< /value> </property> <property > <value>password</value> </property> <property ref = "Casdatasource"/> </bean>
In addition, because the password stored in the database is usually encrypted, so authenticationhandler need to know the encryption method used when matching, in the Deployerconfigcontext.xml file we can for specific The Authenticationhandler class configures a property to specify the cipher class, such as for Querydatabaseauthenticationhandler, which can be modified as shown in Listing 7:
<bean > <property ref= "casdatasource"/> <property value= "Select password from usertable where lower (user Name) = lower (?) "/> <property ref=" Mypasswordencoder "/> </bean>
Where Mypasswordencoder is a reference to the actual cipher class set in Listing 8:
<bean/>
Here Mypasswordencoder is to implement the Passwordencoder interface and its encode () method according to the actual situation of the encryption device.
After the above configuration is complete, several dependent packages need to be copied to the CAS application, including:
Copy the Cas-server-support-jdbc-3.1.1.jar to the%catalina_home%/webapps/cas/web-inf/lib directory. Database driven, because here using DB2, the%db2_home%/java directory under the Db2java.zip (renamed to Db2java.jar), Db2jcc.jar, Db2jcc_license_cu.jar copy to%catalina_ Home%/webapps/cas/web-inf/lib directory. For other databases, the corresponding database driver is also copied to the directory. DataStore relies on Commons-collections-3.2.jar, Commons-dbcp-1.2.1.jar, Commons-pool-1.3.jar, need to download the Commons project to Apache website above 3 A package into the%catalina_home%/webapps/cas/web-inf/lib directory.
CAS provides 2 sets of default pages, "Default" and "simple", respectively, under directory "Cas/web-inf/view/jsp/default" and "Cas/web-inf/view/jsp/simple". The default is a slightly more complex page, using CSS, and simple is the most streamlined to allow CAS to work properly.
Before we deploy CAs, we may need to customize a new set of CAs Server pages to add some personalized content. The simplest way is to copy a default or simple file into the "cas/web-inf/view/jsp" directory, such as named Newui, followed by the implementation and modification of the necessary pages, there are 4 pages are required:
CASCONFIRMVIEW.JSP: When the user selects "Warn", they will see the confirmation interface casgenericsuccess.jsp: The interface casloginview.jsp when the user is successfully authenticated without a destination service: Interface caslogoutview.jsp when users are required to provide authentication information: the interface that appears when a user ends a CAS Single sign-on system session
The CAS pages are written in the spring framework and are familiar to users unfamiliar with spring before they are modified.
After customizing the page, some configuration is needed to allow CAS to find a new page, copy "Cas/web-inf/classes/default_views.properties", and rename it "Cas/web-inf/classes/newui_ Views.properties "and modify all of its values to the corresponding new page. Finally, update the viewresolver in the "cas/web-inf/cas-servlet.xml" file to change it to what is shown in Listing 9.
Listing 9. Specify a CAS page
<bean p:order= "0" > <property > <list> <value>${cas.viewResolver.basename}</value> < value> newui_views</value> </list> </property> </bean>
Deploying Client Apps
The purpose of single sign-on is to allow multiple associated applications to use the same login process, this article constructs 2 simple applications in the course of the tutorial, each with CasTest1 and CasTest2 as an example, they have only one page, display the welcome message and the current login user name. These 2 apps use the same set of login information, and only logged in users can access, through the configuration of this article, to achieve single sign-on, that is, simply log in once to access both applications.
Assuming that CAS server is deployed separately on a machine A, and the client application is deployed on machine B, because the client application communicates with CAS server with SSL, a trust relationship between a and B's JRE needs to be established.
First, like A machine, to generate a certificate on the B machine, configure the Tomcat SSL protocol. Next, download Http://blogs.sun.com/andreas/entry/no_more_unable_to_find Installcert.java, run "Java installcert compa:8443" command, and enter 1 in the next query that appears. In this way, a is added to the trust store of B. If multiple client applications are deployed on separate machines, each machine needs to establish a trust relationship with the machine on which the CAS Server resides.
Configure CAS Filter
Ready to apply CasTest1 and CasTest2, deployed on the B and C machines, respectively, because CasTest1 and Castest2,b and C are identical, we introduce the casTest1 on the B machine, assuming that the domains A and B are respectively D Omaina and DomainB.
Rename the Cas-client-java-2.1.1.zip to Cas-client-java-2.1.1.jar and copy it to the Castest1/web-inf/lib directory, modify the Web. xml file, add the CAs Filter, as listed 10 is shown below:
listing 10. Add CAS Filter
<web-app> ... <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://domainA:8443/cas/login</param-value> </init-param> <init-param> <param-name> Edu.yale.its.tp.cas.client.filter.validateurl</param-name> <param-value>https://domaina:8443/cas/ servicevalidate</param-value> </init-param> <init-param> <param-name> Edu.yale.its.tp.cas.client.filter.servername</param-name> <param-value>domainb:8080</param-value > </init-param> </filter> <filter-mapping> <filter-name>cas filter</filter-name> <url-pattern>/protected-pattern/*</url-pattern> </filter-mapping> </web-app>
For all access to resources that meet the castest1/protected-pattern/path, the CAS Server login is required, and if the entire casTest1 is required to be protected, you can specify Url-pattern as "/*".
As you can see from listing 10, we can specify some parameters for Casfilter, and some of them are necessary, and table 1 and table 2 are the required and optional parameters, respectively:
Table 1. Casfilter Required Parameters
EDU.YALE.ITS.TP.CAS.CLIENT.FILTER.VALIDATEURL Specifies the URL of the CAs to provide service ticket or proxy ticket authentication services Edu.yale.its.tp.cas.clien T.FILTER.SERVERNAME Specifies the domain name and port of the client, which is the machine on which the client application resides instead of the CAS Server, and at least one of the parameters or serviceurl must be specified
Table 2. Casfilter Optional Parameters
Edu.yale.its.tp.cas.client.filter.proxyCallbackUrl gets the address of the proxy granting Ticket for the current application that needs to act as an agent for other services (proxy) Edu.yale.its.tp.cas.client.filter.authorizedProxy is used to allow the current app to obtain a proxy tickets from the proxy, which accepts multiple proxy URLs separated by spaces, But the actual use only needs a success. When you specify this parameter, you need to modify Validateurl to Proxyvalidate instead of Servicevalidate edu.yale.its.tp.cas.client.filter.wrapRequest if specified as True, then Casfilter will repack HttpRequest and have the Getremoteuser () method return the user name of the currently logged-on user
Pass in User name
After successful login, CAS will return cookies to the browser and set up a new Service Ticket. But the client application has its own Session, how do we get the user name of the currently logged in user in each application? The CAS Client Filter has been processed and can be obtained directly from the Session's properties after the login is successful, as shown in Listing 11:
Both of the following can be Session.getattribute (casfilter.cas_filter_user); Session.getattribute ("Edu.yale.its.tp.cas.client.filter.user");
The method of obtaining a user name in JSTL is shown in Listing 12:
<c:out value= "${sessionscope[cas: ' Edu.yale.its.tp.cas.client.filter.user ']}"/>
In addition, CAS provides a Casfilterrequestwrapper class that inherits from Httpservletrequestwrapper, mostly overriding the Getremoteuser () method, as long as it is configured in the previous Casfilter When you set the "edu.yale.its.tp.cas.client.filter.wrapRequest" parameter to True for it, you can obtain the login user name by using the Getremoteuser () method, as shown in Listing 13:
Casfilterrequestwrapper reqwrapper=new Casfilterrequestwrapper (Request); OUT.PRINTLN ("The Logon User:" + reqwrapper.getremoteuser ());
Effect
In CasTest1 and CasTest2, there is a simple Servlet as a welcome page welcompage, and the page must be logged in before it can be accessed, and the page code is shown in Listing 14:
public class Welcomepage extends HttpServlet {public void doget (HttpServletRequest request, httpservletresponse response ) throws IOException, servletexception {response.setcontenttype ("text/html"); PrintWriter out = Response.getwriter (); Out.println ("
After all of the above configurations have been completed, start CAs, CasTest1 and CasTest2 on A, B, and C respectively, and follow the steps below to access CasTest1 and CasTest2:
Figure 2. CAS Login Page
You can see that the address bar in the map has a ticket parameter, which is the ST (Service ticket) that CAS assigns to the current application.
Conclusion
This paper introduces the principle of CAs single sign-on solution, and explains the configuration, deployment method and effect of using CAs in Tomcat with examples. CAS is a good choice for an open source single sign-on solution, with more details on the CAS official website.
Using CAS to implement single sign-on in Tomcat