CAS-4.2.7接入REST登录认证,移动端、C/S端登录解决方案
一、发送GET请求获取RSA公钥和JSESSIONID
请求地址:/cas/login,请求类型:GET
curl -I http://cas.gfstack.geo:8080/cas/login
返回如下:
HTTP/1.1
Set-Cookie: JSESSIONID=2AC7AF14F7798FA770E927F8EFB356FE; Path=/cas; HttpOnly
Set-Cookie: publicKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOrwpYIEi0CTd7TSVqQZ/EhHqysaKT0XEn7pjkO4LQ4g6IfJ/4tcbgn4XpS0cR/9P0WpV93Fsnc40s8VINoMqBH64cNHqE4boEqftRSi/L3FQvMSLxctLavu/kF5bzURPRMPyKlW2FQqMkhVautguT939cu+EitEQKMj29hikAyQIDAQAB; Path=/cas
Cache-Control: no-store
Content-Type: text/html;charset=UTF-
Content-Length:
Date: Tue, May :: GMT
获取到 JSESSIONID 和 publicKey
二、发送POST请求获取请求头中的Location
拿 publicKey 做为RSA公钥对用户密码明文做加密得到 password ,提供java实现,其他语言请自行百度
package com.geostar.gfstack.cas.support.util; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec; /**
* RSA加解密工具类,实现公钥加密私钥解密和私钥解密公钥解密
* link:https://www.cnblogs.com/nihaorz/p/10690643.html
*/
public class RSAUtils { private static final String src = "abcdefghijklmnopqrstuvwxyz"; public static void main(String[] args) throws Exception {
System.out.println("\n");
RSAKeyPair keyPair = generateKeyPair();
System.out.println("公钥:" + keyPair.getPublicKey());
System.out.println("私钥:" + keyPair.getPrivateKey());
System.out.println("\n");
test1(keyPair, src);
System.out.println("\n");
test2(keyPair, src);
System.out.println("\n");
} /**
* 公钥加密私钥解密
*/
private static void test1(RSAKeyPair keyPair, String source) throws Exception {
System.out.println("***************** 公钥加密私钥解密开始 *****************");
String text1 = encryptByPublicKey(keyPair.getPublicKey(), source);
String text2 = decryptByPrivateKey(keyPair.getPrivateKey(), text1);
System.out.println("加密前:" + source);
System.out.println("加密后:" + text1);
System.out.println("解密后:" + text2);
if (source.equals(text2)) {
System.out.println("解密字符串和原始字符串一致,解密成功");
} else {
System.out.println("解密字符串和原始字符串不一致,解密失败");
}
System.out.println("***************** 公钥加密私钥解密结束 *****************");
} /**
* 私钥加密公钥解密
*
* @throws Exception
*/
private static void test2(RSAKeyPair keyPair, String source) throws Exception {
System.out.println("***************** 私钥加密公钥解密开始 *****************");
String text1 = encryptByPrivateKey(keyPair.getPrivateKey(), source);
String text2 = decryptByPublicKey(keyPair.getPublicKey(), text1);
System.out.println("加密前:" + source);
System.out.println("加密后:" + text1);
System.out.println("解密后:" + text2);
if (source.equals(text2)) {
System.out.println("解密字符串和原始字符串一致,解密成功");
} else {
System.out.println("解密字符串和原始字符串不一致,解密失败");
}
System.out.println("***************** 私钥加密公钥解密结束 *****************");
} /**
* 公钥解密
*
* @param publicKeyText
* @param text
* @return
* @throws Exception
*/
public static String decryptByPublicKey(String publicKeyText, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
} /**
* 私钥加密
*
* @param privateKeyText
* @param text
* @return
* @throws Exception
*/
public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
} /**
* 私钥解密
*
* @param privateKeyText
* @param text
* @return
* @throws Exception
*/
public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
} /**
* 公钥加密
*
* @param publicKeyText
* @param text
* @return
*/
public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
} /**
* 构建RSA密钥对
*
* @return
* @throws NoSuchAlgorithmException
*/
public static RSAKeyPair generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
RSAKeyPair rsaKeyPair = new RSAKeyPair(publicKeyString, privateKeyString);
return rsaKeyPair;
} /**
* RSA密钥对对象
*/
public static class RSAKeyPair { private String publicKey;
private String privateKey; public RSAKeyPair(String publicKey, String privateKey) {
this.publicKey = publicKey;
this.privateKey = privateKey;
} public String getPublicKey() {
return publicKey;
} public String getPrivateKey() {
return privateKey;
} } }
将 JSESSION 带到cookie中发送POST请求(参数包含用户名和RSA公钥加密后的密码),请求地址:/cas/v1/tickets,请求类型POST,Content-Type: application/x-www-form-urlencoded
curl -i -X POST \
http://cas.gfstack.geo:8080/cas/v1/tickets \
-H 'Content-Type: application/x-www-form-urlencoded' \
--cookie 'JSESSIONID=2AC7AF14F7798FA770E927F8EFB356FE' \
-d 'username=admin&password=ifP607Amuqxy19VUvZZ79Aq9pTzCYbShrLtSzChhm+GAmtCWUQyryCPjnh7/RhWow2qOSkCy/JynFtkznvwRgofDKN7aCOPDiIEe04IyDMOCEpCws/su+Gp4Jr2kUZHKR6iJ9Ht/adNQqFZ+r2RPiaJSIvNMYSTnY2RBZvwyxNY='
返回如下:
HTTP/1.1
Cache-Control: no-store
Location: http://cas.gfstack.geo:8080/cas/v1/tickets/TGT-6-NK2bhU6TddIyeqmY94BKm2dzFc7BuPQHaMe1pUhX2RrVBmFKQp-cas01.example.org
Content-Type: text/html;charset=UTF-
Content-Length:
Date: Tue, May :: GMT <!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"><html><head><title>201 Created</title></head><body><h1>TGT Created</h1><form action="http://cas.gfstack.geo:8080/cas/v1/tickets/TGT-6-NK2bhU6TddIyeqmY94BKm2dzFc7BuPQHaMe1pUhX2RrVBmFKQp-cas01.example.org" method="POST">Service:<input type="text" name="service" value=""><br><input type="submit" value="Submit"></form></body></html>
获取请求头中的 Location
三、发送POST请求获取ST
请求地址:上一步返回的 Location ,请求类型:POST,Content-Type: application/x-www-form-urlencoded
curl -X POST \
http://cas.gfstack.geo:8080/cas/v1/tickets/TGT-6-NK2bhU6TddIyeqmY94BKm2dzFc7BuPQHaMe1pUhX2RrVBmFKQp-cas01.example.org \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'service=http%3A%2F%2F192.168.36.158%3A8080%2Fdemo%2F'
其中 service 是CAS客户端地址(综合运维、服务中心、数据中心等),需要经过encodeURI编码
返回如下:
ST--kzS0oIyS9DZmveLy4vZs-cas01.example.org
返回内容即是ST,成功拿到ST即成功使用REST登录
四、关于ST校验
请参照:https://www.cnblogs.com/nihaorz/p/10445514.html 部署cas-sample-java-webapp应用完成校验
CAS-4.2.7接入REST登录认证,移动端、C/S端登录解决方案的更多相关文章
- spring boot(十四)shiro登录认证与权限管理
这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在Java领域一般有Spring Security ...
- Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...
- oracle数据库启动流程及登录认证方式详解
转自:https://www.2cto.com/database/201803/726644.html ■ oracle启动流程-windows下 1) lsnrctl start (启动监听) ...
- 混合应用 微信登录授权 微信登录认证失败 ios PGWXAPI错误-1 code:-100 / 安卓 message:invalid appsecret innerCode:40125
最近项目需要做微信登录,于是利用HTML5+ API Reference的OAuth模块管理客户端的用户登录授权验证功能,允许应用访问第三方平台的资源.(链接:https://www.dcloud.i ...
- Oracle登录认证
oracle 登录认证 Table of Contents 1. 简介 2. authentication_services 2.1. 不同登录方式的写法 3. sysdba角色登录认证 3.1. 无 ...
- 实战模拟│JWT 登录认证
目录 Token 认证流程 Token 认证优点 JWT 结构 JWT 基本使用 实战:使用 JWT 登录认证 Token 认证流程 作为目前最流行的跨域认证解决方案,JWT(JSON Web Tok ...
- DRF接入Oauth2.0认证[微博登录]报错21322重定向地址不匹配
DRF接入Oauth2.0认证[微博登录]报错21322重定向地址不匹配 主题自带了微博登陆接口,很简单的去新浪微博开放平台创建了网页应用,然后把APP ID和 AppSecret填好后,以为大功告成 ...
- cas-5.3.x接入REST登录认证,移动端登录解决方案
一.部署cas-server及cas-sample-java-webapp 1.克隆cas-overlay-template项目并切换到5.3分支 git clone git@github.com:a ...
- Spring Security OAuth2 微服务认证中心自定义授权模式扩展以及常见登录认证场景下的应用实战
一. 前言 [APP 移动端]Spring Security OAuth2 手机短信验证码模式 [微信小程序]Spring Security OAuth2 微信授权模式 [管理系统]Spring Se ...
- ELK日志系统:Filebeat使用及Kibana如何设置登录认证
根据elastic上的说法: Filebeat is a lightweight, open source shipper for log file data. As the next-generat ...
随机推荐
- Qt 遍历不规则树的节点
在使用Qt的GraphicsScene作图时,遇到类似这样的需求:在scene中创建节点类似下图, 现在我要把每个节点的txt保存到xml文件中,结构为 <?xml version='1.0' ...
- Codeforces 1262D Optimal Subsequences(BIT+二分)
首先比较容易想到肯定是前k大的元素,那么我们可以先对其进行sort,如果数值一样返回下标小的(见题意),接下里处理的时候我们发现需要将一个元素下标插入到有序序列并且需要访问第几个元素是什么,那么我们可 ...
- php配置伪静态如何将.htaccess文件转换 nginx伪静态文件
php通常设置伪静态三种情况,.htaccess文件,nginx伪静态文件,Web.Config文件得形式,如何将三种伪静态应用到项目中呢, 1,.htaccess文件 实例 <IfModule ...
- LeetCode 235. 二叉搜索树的最近公共祖先
235. 二叉搜索树的最近公共祖先 题目描述 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先 ...
- Django rest_frameword 之项目流程
后端开发软件目录规范 一.Model from django.db import models # Create your models here. # 多表的设计 # 图书 作者 出版社 作者详情表 ...
- linux MySql 的主从复制部署
MySql 复制 mysql 复制:将某一台主机上的 Mysql 数据复制到其它主机(slaves)上,并重新执行一遍从而实现 当前主机上的 mysql 数据与(master)主机上数据保持一致的过程 ...
- Python自动化学习--鼠标和键盘事件
from selenium import webdriver from selenium.webdriver import ActionChains import time driver = webd ...
- 个人第二次作业-c++实现四则运算生成器
c++实现四则运算生成器 GIT地址 Link Git用户名 Redwarx008 学号后五位 61128 博客地址 Link 作业链接 Link 环境配置 使用VS2019社区版,一键式安装,这里不 ...
- Laplace's equation
链接:https://en.wikipedia.org/wiki/Laplace%27s_equation
- hdu4731 Minimum palindrome (找规律)
这道题找下规律,3个字母或者以上的时候就用abcabcabc....循环即可. 一个字母时,就是aaaaa.....; 当只有2个字母时!s[1][]=a"; s[2][]="ab ...