cas-overlay-template-5.3 集成REST 协议
程序员文章站
2022-03-08 20:10:03
...
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);
}
}
下一篇: 老爱放屁的中医处理办法
推荐阅读
-
typescript-koa-postgresql 实现一个简单的rest风格服务器 —— 集成 koa
-
安防视频监控系统视频上云解决方案EasyCVR集成海康EHome私有协议系列:设备录像流数据进行PS包分割
-
Swagger 与 Spring Boot REST API 集成
-
SpringBoot2.x系列教程(四十六)Spring Boot集成WebSocket之STOMP协议简介
-
typescript-koa-postgresql 实现一个简单的rest风格服务器 —— 集成 koa
-
图数据库实践系列 (三)--Neo4j Spatial的REST集成
-
dubbo-go 中 REST 协议实现
-
Netty集成ProtoBuf开发私有协议
-
Spring REST集成测试示例
-
springboot 结合zookeeper,dubbo,支持dubbo,rest协议