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);
	}
}
发布了1266 篇原创文章 · 获赞 275 · 访问量 290万+

猜你喜欢

转载自blog.csdn.net/zhouzhiwengang/article/details/104893272