cas-overlay-template-5.3 集成REST 协议分析

阿里 阅读:335 2021-03-31 16:51:44 评论:0

CAS5 通过rest 接口实现登入

1、添加maven 依赖:

	            <!-- 开启rest支持 --> 
				<dependency> 
					<groupId>org.apereo.cas</groupId> 
					<artifactId>cas-server-support-rest</artifactId> 
					<version>${cas.version}</version> 
				</dependency>

2、postman 模拟测试功能截图:

第一步:通过用户名和密码来获取tgt

第二步:通过tgt来获取st

第三步:验证st,返回用户相关信息

第四步:删除TGT

第五步:校验TGT

功能实现说明:

1:ssm框架项目(前后端在同一域名下,且集成cas5客户端)
      rest 协议实现步骤一+步骤二,完成用户的单点登入
2:  springboot 微服务项目 +vue 前端项目(不在同一域名下,没有集成cas5 客户端)
     rest 协议实现步骤1~ 步骤五,实现用户单点认证。

核心功能代码:

 
 
import java.net.URLEncoder; 
import java.util.HashMap; 
import java.util.Map; 
import org.apache.commons.lang3.StringUtils; 
import org.jsoup.Jsoup; 
import org.jsoup.nodes.Document; 
import org.jsoup.select.Elements; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 
 
 
@Component("casServerUtil") 
public class CasServerUtil { 
	@Autowired 
	private CasServerProperties properties; 
	 
	/** 
	 * 功能概述:验证用户提供的oauth2.0 的accessToken 是否合法 
	 * @param accessToken 
	 * @return 
	 */ 
	public String validateAccessToken(String accessToken){ 
		Map<String, Object> map = new HashMap<>(); 
        map.put("access_token", accessToken.trim()); 
        return HTTPUtil.doGet(this.properties.getAccessTokenPath(), map); 
	} 
 
    /** 
     * 功能概述:获取到 (Tokent generate tiker ,token生成票据)tgt 
     * @return 
     */ 
    public String getTGT(String username,String password){ 
        String tgt = ""; 
        try {             
            Map<String, Object> map = new HashMap<>(); 
            map.put("username", URLEncoder.encode(username, "UTF-8")); 
            map.put("password", URLEncoder.encode(password, "UTF-8")); 
            String html = HTTPUtil.doPost(this.properties.getTicketPath(), map); 
             
            Document document = Jsoup.parse(html); 
            Elements elements = document.select("form"); 
            tgt = elements.attr("action"); 
           
            if (tgt != null) { 
                  tgt = tgt.substring(tgt.lastIndexOf("/") + 1); 
            } 
        } catch (Exception e) { 
            return ""; 
        } 
        return tgt; 
    } 
     
    
 
    /** 
     * 功能概述:根据票据生成工具,获取st 
     * @param tgt 
     * @return 
     */ 
    public String getST(String tgt){ 
        String serviceTicket = ""; 
        try { 
        	//获取返回的ticket票据 
        	Map<String, Object> map = new HashMap<>(); 
            map.put("service", this.properties.getDomain()); 
            serviceTicket = HTTPUtil.doPost(this.properties.getTicketPath()+"/"+tgt, map); 
        } catch (Exception e) { 
            return ""; 
        } 
        return serviceTicket; 
    } 
     
    /** 
     * 功能概述:验证st的合法性 
     * @param tgt 
     * @return 
     */ 
    public boolean validateST(String st){ 
    	//获取返回的ticket票据 
    	Map<String, Object> map = new HashMap<>(); 
        map.put("service", this.properties.getDomain()); 
        map.put("ticket", st); 
         
        String html = HTTPUtil.doGet(this.properties.getValidatePath(), map); 
        if(StringUtils.isEmpty(html)){ 
        	return false; 
        } 
        return html.contains("<cas:authenticationSuccess>"); 
    } 
     
    /** 
     * 功能概述:验证st的合法性 
     * @param tgt 
     * @return 
     */ 
    public String getContent(String st){ 
    	//获取返回的ticket票据 
    	Map<String, Object> map = new HashMap<>(); 
        map.put("service", this.properties.getDomain()); 
        map.put("ticket", st); 
         
        return HTTPUtil.doGet(this.properties.getValidatePath(), map); 
    } 
     
    public String deleteTGT(String tgt){ 
    	Map<String, Object> map = new HashMap<>(); 
    	map.put("ticket", tgt); 
    	return HTTPUtil.doDelete(this.properties.getTicketPath(), map); 
    } 
     
     
    /** 
     * 机能概要: 先通过用户名密码, 
     * 先生成tikect的 token,然后再通过token获取到id 
     * @param args 
     * @throws Exception 
    */ 
   public static void main(String [] args) throws Exception { 
 
 
//       String username ="admin"; 
//       String password ="123456"; 
// 
// 
//       CasServerUtil utils = CasServerUtil.getInstance(); 
//       String tgt = utils.getTGT(username, password); 
//       System.out.println("用户登入凭证:" + tgt); 
//       String st = utils.getSt(tgt); 
//       System.out.println("授权凭证:" + st); 
//        
//       boolean target = utils.validateST(st); 
//       System.out.println("是否有效授权凭证:" + target); 
        
        
   } 
 
     
     
 
} 
 
 
import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 
import org.apache.http.HttpEntity; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.CloseableHttpResponse; 
import org.apache.http.client.methods.HttpDelete; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.client.utils.URIBuilder; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClients; 
import org.apache.http.message.BasicNameValuePair; 
import org.apache.http.util.EntityUtils; 
 
/** 
 * 基于HttpClient 封装post 和 get 请求 
 *  
 * @author zzg 
 * 
 */ 
public class HTTPUtil { 
	public static String doGet(String url, Map<String, Object> map) { 
		String strResult = ""; 
		// 4. 获取默认的client实例 
		CloseableHttpClient client = HttpClients.createDefault(); 
		try { 
 
			// 1.创建URIBuilder 
			URIBuilder uriBuilder = new URIBuilder(url); 
 
			// 2.设置请求参数 
			if (map != null) { 
				// 遍历请求参数 
				for (Map.Entry<String, Object> entry : map.entrySet()) { 
					// 封装请求参数 
					uriBuilder.setParameter(entry.getKey(), entry.getValue().toString()); 
				} 
			} 
 
			// 3.创建请求对象httpGet 
			HttpGet httpGet = new HttpGet(uriBuilder.build()); 
 
			// 4.使用httpClient发起请求 
			CloseableHttpResponse response = client.execute(httpGet); 
			try { 
				// 5. 获取响应entity 
				HttpEntity respEntity = response.getEntity(); 
				strResult = EntityUtils.toString(respEntity, "UTF-8"); 
			} finally { 
				// 6. 关闭响应对象 
				response.close(); 
			} 
 
		} catch (Exception e) { 
			e.printStackTrace(); 
		} finally { 
			// 7. 关闭连接,释放资源 
			try { 
				client.close(); 
			} catch (Exception e) { 
				e.printStackTrace(); 
			} 
		} 
 
		return strResult; 
	} 
 
	/** 
	 * 普通POST提交 
	 *  
	 * @param url 
	 * @param map 
	 * @return 
	 */ 
	public static String doPost(String url, Map<String, Object> map) { 
		String strResult = ""; 
		// 1. 获取默认的client实例 
		CloseableHttpClient client = HttpClients.createDefault(); 
		// 2. 创建httppost实例 
		HttpPost httpPost = new HttpPost(url); 
		// 3. 创建参数队列(键值对列表) 
		List<NameValuePair> paramPairs = new ArrayList<>(); 
		Set<String> keySet = map.keySet(); 
		for (String key : keySet) { 
			Object val = map.get(key); 
			paramPairs.add(new BasicNameValuePair(key, val.toString())); 
		} 
		UrlEncodedFormEntity entity; 
		try { 
			// 4. 将参数设置到entity对象中 
			entity = new UrlEncodedFormEntity(paramPairs, "UTF-8"); 
			// 5. 将entity对象设置到httppost对象中 
			httpPost.setEntity(entity); 
			// 6. 发送请求并回去响应 
			CloseableHttpResponse resp = client.execute(httpPost); 
			try { 
				// 7. 获取响应entity 
				HttpEntity respEntity = resp.getEntity(); 
				strResult = EntityUtils.toString(respEntity, "UTF-8"); 
			} finally { 
				// 9. 关闭响应对象 
				resp.close(); 
			} 
 
		} catch (ClientProtocolException e) { 
			e.printStackTrace(); 
		} catch (UnsupportedEncodingException e) { 
			e.printStackTrace(); 
		} catch (IOException e) { 
			e.printStackTrace(); 
		} finally { 
			// 10. 关闭连接,释放资源 
			try { 
				client.close(); 
			} catch (Exception e) { 
				e.printStackTrace(); 
			} 
		} 
		return strResult; 
	} 
 
	public static String doDelete(String url, Map<String, Object> map) { 
		String strResult = ""; 
		// 1. 获取默认的client实例 
		CloseableHttpClient client = HttpClients.createDefault(); 
 
		try { 
			// 2.创建URIBuilder 
			StringBuilder builder = new StringBuilder(); 
			builder.append(url); 
			// 3.设置请求参数 
			if (map != null) { 
				// 遍历请求参数 
				for (Map.Entry<String, Object> entry : map.entrySet()) { 
					// 封装请求参数 
					builder.append("/").append(entry.getValue().toString()); 
				} 
			} 
			// 4. 创建httpDelete实例 
			HttpDelete httpDelete = new HttpDelete(builder.toString()); 
			// 5.使用httpClient发起请求 
			CloseableHttpResponse response = client.execute(httpDelete); 
			try { 
				// 5. 获取响应entity 
				HttpEntity respEntity = response.getEntity(); 
				strResult = EntityUtils.toString(respEntity, "UTF-8"); 
			} finally { 
				// 6. 关闭响应对象 
				response.close(); 
			} 
 
		} catch (Exception e) { 
			e.printStackTrace(); 
		} finally { 
			// 7. 关闭连接,释放资源 
			try { 
				client.close(); 
			} catch (Exception e) { 
				e.printStackTrace(); 
			} 
		} 
		return strResult; 
	} 
 
} 
 
 
import org.springframework.boot.context.properties.ConfigurationProperties; 
import org.springframework.context.annotation.Configuration; 
 
@Configuration 
@ConfigurationProperties(prefix = "com.***") 
public class CasServerProperties { 
	// cas 服务器地址 
	private String casServerPath; 
	// ticket 地址 
	private String ticketPath; 
	// 校验ticket 地址 
	private String validatePath; 
	// 绑定域名地址 
	private String domain; 
	// oath2.0 验证token 地址 
	private String accessTokenPath; 
	 
	public String getCasServerPath() { 
		return casServerPath; 
	} 
	public void setCasServerPath(String casServerPath) { 
		this.casServerPath = casServerPath; 
	} 
	public String getTicketPath() { 
		return ticketPath; 
	} 
	public void setTicketPath(String ticketPath) { 
		this.ticketPath = ticketPath; 
	} 
	public String getValidatePath() { 
		return validatePath; 
	} 
	public void setValidatePath(String validatePath) { 
		this.validatePath = validatePath; 
	} 
	public String getDomain() { 
		return domain; 
	} 
	public void setDomain(String domain) { 
		this.domain = domain; 
	} 
	public String getAccessTokenPath() { 
		return accessTokenPath; 
	} 
	public void setAccessTokenPath(String accessTokenPath) { 
		this.accessTokenPath = accessTokenPath; 
	} 
 
} 

application.properties 配置属性:

# 配置cas 服务器地址 
com.***.casServerPath=http://192.168.1.1:8098/cas 
com.***..ticketPath=${com.digipower.casServerPath}/v1/tickets 
com.***..validatePath=${com.digipower.casServerPath}/p3/serviceValidate 
com.***..accessTokenPath=${com.digipower.casServerPath}/oauth2.0/profile 
com.***..domain=http://192.168.1.1:8090
@Controller 
@RequestMapping("/sso/ticket") 
@Api(value = "凭证校验Controller", tags = "凭证校验服务") 
public class TicketValidateController { 
	public static final Logger log = LoggerFactory.getLogger(TicketValidateController.class); 
 
	@Autowired 
	private CasServerUtil util; 
	 
 
	@ApiOperation(httpMethod = "GET", value = "凭证生成") 
	@RequestMapping(value = "/validate", method = { RequestMethod.POST, 
			RequestMethod.GET }, produces = "application/json;charset=UTF-8") 
	@ResponseBody 
	public Result validate(HttpServletRequest request, HttpServletResponse response) { 
		String tgt = request.getParameter("ticket"); 
 
		// 判断tgt是否为空 
		if (StringUtils.isEmpty(tgt)) { 
			return Result.error(Result.RESULT_CODE_TGT_NULL, "用户TGT凭证为空 ") 
					.setDatas(Result.RESULT_CODE_NOT_REGISTRY_SESSION, "用户TGT凭证为空"); 
		} 
 
		String st = util.getST(tgt); 
 
		// ST 查询关联用户, 模拟用户登入凭证 
		String content = util.getContent(st); 
		// 用户信息 
		String username = ""; 
		// 解析 
		try { 
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
			DocumentBuilder builder = factory.newDocumentBuilder(); 
			Document doc = builder.parse(new InputSource(new StringReader(content))); 
			Element root = doc.getDocumentElement(); 
			NodeList nodeList = root.getElementsByTagName("cas:user"); 
			if (nodeList != null) { 
				for (int i = 0; i < nodeList.getLength(); i++) { 
					Node user = nodeList.item(i); 
					username = user.getTextContent(); 
				} 
			} 
		} catch (Exception e) { 
			log.error(e.getMessage()); 
			return Result.error(Result.RESULT_CODE_TGT_ERROR, "用户TGT凭证为空 ") 
					.setDatas(Result.RESULT_CODE_NOT_REGISTRY_SESSION, "CAS REST服务异常"); 
 
		} 
		// 生成jwt 信息 返回前端 
		Map<String, Object> paramter = new HashMap<String, Object>(); 
		if (!StringUtils.isEmpty(username)) { 
			paramter.put("username", username); 
			paramter.put("tgt", tgt); 
		} 
		// 生成jwt token 
		String token = JwtTokenUtil.createToken(paramter); 
		return Result.ok().setDatas(Result.RESULT_CODE_SUCCESS, "用户登入成功").setDatas("token", token); 
	} 
}

 

声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
KIKK导航

KIKK导航

排行榜
关注我们

一个IT知识分享的公众号