上一篇主要讲述了CAS的Server端的配置和使用,点击这里进行回顾。这篇则讲述CAS的客户端的使用,主要是JAVA客户端以及RESTFUL接口
上一篇中讲过,使用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
增加所需的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>
可能还需要加入一些其他常用的包,根据需要来添加。
增加:
<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个过滤器,分别用来验证、认证和附加一些信息(如登录者的信息等)
另外,如果使用HTTPS,似乎必须使用域名,用IP则会出错。若是HTTP,则不影响。
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:[email protected]">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