cas-overlay-template-5.3 集成REST 協議

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);
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章