前言
上一篇主要讲述了CAS的Server端的配置和使用,点击这里进行回顾。这篇则讲述CAS的客户端的使用,主要是JAVA客户端以及RESTFUL接口
一、为WEB应用配置CAS认证
1.给WEB应用所部署的Servlet容器打证书
上一篇中讲过,使用HTTPS通信,做过一个证书库。这里还需要使用它。如果不是用HTTPS,就不用这一步了。
caserver 生成的 tomcat.keystore 导出一个子认证. 然后这个子认证要导入到java 单点客户端jdk认证库里. 这样子系统与单点服务系统建立了验证关系. 当然如果单点服务与单点客户端在同一台机器上,共用一个jdk,就不存在这个证书的导入与验证了.
将认证导入到jdk认证库cacerts中
keytool -import -trustcacerts -alias javacas -file "D:/Program Files/Apache Software Foundation/Tomcat 6.0/conf/myserver.cert" -keypass 123456 -keystore "%JAVA_HOME%/jre/lib/security/cacerts"
cacerts是java默认的认证库,默认密码为:changeit
2.修改WEB应用
(参考官方例子)
增加CAS Client到客户应用
增加所需的cas-client-core包,当前版本是3.1.10.可以直接下载拷贝到WEB-INF/lib,
使用maven可以加入以下代码
<dependency> <groupId>org.jasig.cas</groupId> <artifactId>cas-client-core</artifactId> <version>3.1.10</version> </dependency>
可能还需要加入一些其他常用的包,根据需要来添加。
修改web.xml
增加:
<context-param> <param-name>serverName</param-name> <param-value>http://localhost:8080</param-value> </context-param> <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>http://wzfedora:8080/cas-server-webapp/login</param-value> <param-value>https://wzfedora:8443/cas-server-webapp/login</param-value> --> <param-value>http://10.1.81.235/cas/login</param-value> </init-param> </filter> <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>http://10.1.81.235/cas</param-value> <!-- <param-value>https://wzfedora:8443/cas-server-webapp</param-value> <param-value>http://wzfedora:8080/cas-server-webapp</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-mapping> <filter-name>CAS Authentication Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
说明:
这里配置了3个过滤器,分别用来验证、认证和附加一些信息(如登录者的信息等)
- CAS Validation Filter 其中的Cas20ProxyReceivingTicketValidationFilter的20表示使用CAS 2.0协议
- CAS Authentication Filter
- CAS HttpServletRequest Wrapper Filter
另外,如果使用HTTPS,似乎必须使用域名,用IP则会出错。若是HTTP,则不影响。
二、客户端调用REST接口
CAS Server端配置REST支持已经再上篇中讲述了,点这里查看。官方的地址请点击这里。
再RESTFul中,TGT被暴露当作资源,拥有唯一的URI. The RESTful API follows the same basic protocol as the original CAS2 protocol
RESTful API遵循CAS2基础协议.
下面是一个JAVA客户端调用的例子
import java.io.IOException;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
/**
* An example Java client to authenticate against CAS using REST services.
* Please ensure you have followed the necessary setup found on the <a
* href="http://www.ja-sig.org/wiki/display/CASUM/RESTful+API">wiki</a>.
*
* @author <a href="mailto:jieryn@gmail.com">jesse lauren farinacci</a>
* @since 3.4.2
*/
public final class Client
{
private static final Logger LOG = Logger.getLogger(Client.class.getName());
private Client()
{
// static-only access
}
public static String getTicket(final String server, final String username,
final String password, final String service)
{
notNull(server, "server must not be null");
notNull(username, "username must not be null");
notNull(password, "password must not be null");
notNull(service, "service must not be null");
return getServiceTicket(server, getTicketGrantingTicket(server, username,
password), service);
}
private static String getServiceTicket(final String server,
final String ticketGrantingTicket, final String service)
{
if (ticketGrantingTicket == null)
return null;
final HttpClient client = new HttpClient();
final PostMethod post = new PostMethod(server + "/" + ticketGrantingTicket);
post.setRequestBody(new NameValuePair[] { new NameValuePair("service",
service) });
try
{
client.executeMethod(post);
final String response = post.getResponseBodyAsString();
switch (post.getStatusCode())
{
case 200:
return response;
default:
LOG.warning("Invalid response code (" + post.getStatusCode()
+ ") from CAS server!");
LOG.info("Response (1k): "
+ response.substring(0, Math.min(1024, response.length())));
break;
}
}
catch (final IOException e)
{
LOG.warning(e.getMessage());
}
finally
{
post.releaseConnection();
}
return null;
}
private static String getTicketGrantingTicket(final String server,
final String username, final String password)
{
final HttpClient client = new HttpClient();
final PostMethod post = new PostMethod(server);
post.setRequestBody(new NameValuePair[] {
new NameValuePair("username", username),
new NameValuePair("password", password) });
try
{
client.executeMethod(post);
final String response = post.getResponseBodyAsString();
switch (post.getStatusCode())
{
case 201:
{
final Matcher matcher = Pattern.compile(".*action=\".*/(.*?)\".*")
.matcher(response);
if (matcher.matches())
return matcher.group(1);
LOG
.warning("Successful ticket granting request, but no ticket found!");
LOG.info("Response (1k): "
+ response.substring(0, Math.min(1024, response.length())));
break;
}
default:
LOG.warning("Invalid response code (" + post.getStatusCode()
+ ") from CAS server!");
LOG.info("Response (1k): "
+ response.substring(0, Math.min(1024, response.length())));
break;
}
}
catch (final IOException e)
{
LOG.warning(e.getMessage());
}
finally
{
post.releaseConnection();
}
return null;
}
private static void notNull(final Object object, final String message)
{
if (object == null)
throw new IllegalArgumentException(message);
}
public static void main(final String[] args)
{
final String server = "http://10.1.81.235/cas/v1/tickets";
final String username = "admin";
final String password = "admin123";
final String service = "http://localhost:8080/casclientweb";
LOG.info(getTicket(server, username, password, service));
}
}
运行结果如下
2012-4-11 16:05:48 Client main
信息: ST-4-J0IQnprd2DhJlku059gw-cas