问卷/试卷服务
成长值服务
短信服务

单点登录cas版

一、使用前必读

统一认证支撑平台业务系统前台单点登录服务端测试地址:

http://10.10.6.21:8081/uumlogin/login

测试账号、密码:

441502199212204034 、Tcinterlib@12

因现在系统分为中台版和单体版

如中台版需要用到原有token的方式,则需要在登录的时候调用中台版用户中心登录接口获取token。【这样改动不会太大】

单体版系统退出方式:直接调用http://ip:port/uumlogin/logout

下面三种方式名词解释

ip:port 单点登录服务器地址 clientIp:clientPort 客户端服务器地址

返回状态码

状态码 描述
403 用户不可用
404 账号不存在
423 账户被锁定
428 过期
其他 登录失败

INVALID_REQUEST_PROXY=必须同时提供'pgt'和'targetService'参数 INVALID_TICKET_SPEC=校验票根失败。您可能采用服务票根来校验代理票根,或没有将renew设为true。 INVALID_REQUEST=必须同时提供'service'和'ticket'参数 INVALID_TICKET=未能够识别出目标 ''{0}''票根 INVALID_SERVICE=票根''{0}''不符合目标服务

第三种方式 第三个接口返回xml节点为

<cas:authenticationSuccess >则表示登录成功

<cas:authenticationFailure >则表示登录失败

二、对接提供三种方式

1.使用单点认证登录页面

1.1.把cas-client-core.jar包放进工程,

maven版本:

`
<dependency> 
<groupId>org.jasig.cas.client</groupId> 
<artifactId>cas-client-core</artifactId> 
<version>3.2.1</version> 
</dependency>

`

本地版本: jar下载地址:http://www.java2s.com/Code/JarDownload/cas-client/cas-client-core-3.2.1.jar.zip

1.2.配置你们的web.xml

 <!-- ======================== 单点登录开始 ======================== -->
	<!-- 用于单点退出,该过滤器用于实现单点登出功能,可选配置-->
	<listener>
		<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
	</listener>

	<!-- 该过滤器用于实现单点登出功能,可选配置。 -->
	<filter>
		<filter-name>CAS Single Sign Out Filter</filter-name>
		<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS Single Sign Out Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<filter>
		<filter-name>CAS Filter</filter-name>
		<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
		<init-param>
			<param-name>casServerLoginUrl</param-name>
			<param-value>http://ip:port/uumlogin/login</param-value>
		</init-param>
		<init-param>
			<param-name>serverName</param-name>
			<param-value>http://ip:port</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CAS Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
	<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://ip:port/uumlogin</param-value>
		</init-param>
		<init-param>
			<param-name>serverName</param-name>
			<param-value>http://ip:port</param-value>
		</init-param>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CAS Validation Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!--
		该过滤器负责实现HttpServletRequest请求的包裹,
		比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。
	-->
	<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 HttpServletRequest Wrapper Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

   <!--
	该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。
	比如AssertionHolder.getAssertion().getPrincipal().getName()。
	-->
	<filter>
		<filter-name>CAS Assertion Thread Local Filter</filter-name>
		<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS Assertion Thread Local Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- ===你自定义的过滤器,用来获取单点登录成功后的用户信息 ==== -->
	 <filter>
<filter-name>SSOReaderLoginFilter</filter-name>
<filter-class>com.interlib.sso.filter.SSOReaderLoginFilter</filter-class>
	 </filter>
	 <filter-mapping>
		   <filter-name>SSOReaderLoginFilter</filter-name>
		   <url-pattern>/*</url-pattern>
	 </filter-mapping>
	    <!-- end -->
     <!-- 单点登录结束 -->

1.3.编写拦截器

参考示例:SSOReaderLoginFilter.java

package com.onecard.interlib.common.filter;

import com.interlib.sso.domain.Reader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SSOReaderLoginFilter implements Filter{
  private final Logger log = LoggerFactory.getLogger(getClass());
  
  public void destroy() {}
  
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
    throws IOException, ServletException
  {
    this.log.info("cas Loign filter");
    HttpServletRequest request = (HttpServletRequest)req;
    HttpServletResponse response = (HttpServletResponse)resp;
    HttpSession session = request.getSession();
  
    AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();
  if (principal != null){
//		    this.log.info("principal不为空 -我进来这里了");

			Map<String, Object> attributes = principal.getAttributes();
			System.out.println("attributes=="+attributes);

		    String rdId= (String) attributes.get("rdId");//读者证号
		  
		  
		    String rdPasswd= (String) attributes.get("rdPasswd");//读者密码
		    String rdName= (String)attributes.get("rdName") == null ? "" :  (String)attributes.get("rdName");//读者姓名
		    String rdLoginId= (String)attributes.get("rdLoginId") == null ? "" :  (String)attributes.get("rdLoginId");//手机号
		    String rdCertify= (String)attributes.get("rdCertify") == null ? "" :  (String)attributes.get("rdCertify");//身份证号

		    String rdUnit= (String)attributes.get("rdUnit") == null ? "" :  (String)attributes.get("rdUnit");//单位
		    String rdEmail= (String)attributes.get("rdEmail") == null ? "" :  (String)attributes.get("rdEmail");//邮箱
		    String rdType= (String)attributes.get("rdType") == null ? "999_GJ" :  (String)attributes.get("rdType");//读者类型
		    int rdSex;//性别
		    if(attributes.get("rdSex") != null){
		    	rdSex= Integer.parseInt(((String) attributes.get("rdSex")).trim());
		    }else{
		    	rdSex= 1;
		    }
		    int rdCFState;//读者状态
		    if(attributes.get("rdCFState") != null){
		    	rdCFState= Integer.parseInt(((String) attributes.get("rdCFState")).trim());
		    }else{
		    	rdCFState= 1;
		    }
		    String rdLib= (String)attributes.get("rdLib") == null ? "999" :  (String)attributes.get("rdLib");//馆代码

		    Date rdBornDate = null;//出生日期
		    if(attributes.get("rdBornDate") == null){
		    	rdBornDate = null;
		    }else{
		  
		    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		    	try {
					rdBornDate =  sdf.parse((String)attributes.get("rdBornDate"));
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		    }
		    Date rdStartDate = null;//证启用时间
		    if(attributes.get("rdStartDate") == null){
		    	 rdStartDate = null;
		    }else{
		    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		    	try {
		    		rdStartDate =  sdf.parse((String)attributes.get("rdStartDate"));
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		    }
		    Date rdEndDate = null;//证终止时间
		    if(attributes.get("rdEndDate") == null){
		    	rdEndDate = null;
		    }else{
		    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		    	try {
		    		rdEndDate =  sdf.parse((String)attributes.get("rdEndDate"));
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		    }
		    Date rdInTime = null;//办证时间
		    if(attributes.get("rdInTime") == null){
		    	rdInTime = null;
		    }else{
		    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		    	try {
		    		rdInTime =  sdf.parse((String)attributes.get("rdInTime"));
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		    }
		    String rdAddress= (String)attributes.get("rdAddress") == null ? "" : (String)attributes.get("rdAddress");//住址
   
//		    this.log.info("单点登录的用户为:" + rdId);
		    Reader reader = new Reader();

		    reader.setRdId(rdId);
		    reader.setRdPasswd(rdPasswd);
		    reader.setRdName(rdName);
		    reader.setRdLoginId(rdLoginId);
		    reader.setRdCertify(rdCertify);
		    reader.setRdCFState((byte)rdCFState);
		    reader.setRdEmail(rdEmail);
		    reader.setRdType(rdType);
		    reader.setRdSex((byte)rdSex);
		    reader.setRdLib(rdLib);
		    reader.setRdUnit(rdUnit);
		    reader.setRdAddress(rdAddress);
		    reader.setRdInTime(rdInTime);
		    reader.setRdBornDate(rdBornDate);
		    reader.setRdStartDate(rdStartDate);
		    reader.setRdEndDate(rdEndDate);
//			System.out.println("rdCertify:"+rdCertify);
		   
		  ReaderSession readerSession = new ReaderSession();
          readerSession.setReader(reader);

	chain.doFilter(request, response);
  }
  
  public void init(FilterConfig arg0)
    throws ServletException
  {}
}

2.不采用登录页面,使用自己的页面进行登录

2.1.需要配置好第一种对接方式

2.2.登录框配置信息


<form method="POST" action="http://ip:port/uumlogin/login">
        <p>用户名 : <input type="text" name="username"></p>
        <p>密  码 : <input type="password" name="password"></p>
        <p><input type="submit" value="登录" class="input"></p>
        <input type="hidden" name="auto" value="true">
        <input type="hidden" name="service" value="子系统地址">
    </form>

<input type="hidden" name="service" value="" />  这里的value不填则为本应用登录,填则会跳转到其他应用

2.3.退出

可以直接调 http://ip:port/uumlogin/logout 这个接口

3.前后端分离(PC门户、移动门户、APP、小程序等)对接方式

接口传输密码为des加密,密钥为64074f968502295ca41b7db452c7c639

import CryptoJS from 'crypto-js'
/**
 * 加密(需要先加载lib/aes/aes.min.js文件)
 */
export const encrypt = (word) => {
    var key = CryptoJS.enc.Utf8.parse("64074f968502295ca41b7db452c7c639");
    var srcs = CryptoJS.enc.Utf8.parse(word);
    var encrypted = CryptoJS.DES.encrypt(srcs, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return encrypted.toString();
}
/**
 * 解密
 */
export const decrypt = (word) => {
    var key = CryptoJS.enc.Utf8.parse("46cc793c53dc451b");
    var decrypt = CryptoJS.DES.decrypt(word, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return CryptoJS.enc.Utf8.stringify(decrypt).toString();
}

3.1.获取TGT

发送POST请求,获取TGT,请求地址 http://ip:port/uumlogin/v1/tickets,请求响应头中的Location即包含uumlogin服务器返回的TGT 请求参数为 service 客户端地址 username 读者证号 bbc 读者密码

lombok

3.2.获取ST

发送POST请求,获取ST,直接使用第一步中返回的Location作为请求地址,service参数为客户端地址

http://ip:port/uumlogin/v1/tickets/{TGT}

lombok

3.3.校验ST

校验ST的真实性,以防ST伪造,并完成登录获取被保护后台的读者证号,用于访问其服务。至此,登录完成。

GET 请求 http://ip:port/uumlogin/p3/serviceValidate?service={service}&ticket={ticket}

service 客户端地址

ticket 上一步拿到的ST票据

返回读者证号,则认证成功

lombok

3.4.请求地址

访问地址携带ticket

http://客户端地址/?ticket={ticket}

3.5.退出

DELETE http://ip:port/uumlogin/v1/tickets/{TGT}

三、获取用户信息

attributes所有的信息参数如下:

信息属性 中文解释
rdId 读者证号
rdPasswd 读者密码 [没有加密]
rdName 读者姓名
rdLoginId 手机号
rdCertify 身份证号
rdBornDate 出生日期:(精确到了年月日)
rdEmail 邮箱地址
rdType 读者类型
rdAddress 住址,
rdSex 性别(1:男 2:女),
rdCFState 读者状态
rdLib 馆代码
rdInTime 办证日期:(精确到了年月日)
dueTime 读者更新时间
rdStartDate 读者证开始日期:(精确到了年月日)
rdEndDate 读者证终止日期:(精确到了年月日)
rdUnit 单位