网易企业邮箱单点登录优化
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
package org.maxkey.authz.exapi.endpoint;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.authz.exapi.endpoint.adapter.netease.NeteaseRSATool;
|
||||
import org.maxkey.pretty.impl.JsonPretty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
@Tag(name = "2-8-ExtendApi接口文档模块-元数据")
|
||||
@Controller
|
||||
public class ExtendApiMetadata {
|
||||
final static Logger _logger = LoggerFactory.getLogger(ExtendApiMetadata.class);
|
||||
|
||||
@Operation(summary = "netease qiye mail RSA Key", description = "网易企业邮箱RSA Key生成器",method="GET")
|
||||
@RequestMapping(
|
||||
value = "/metadata/netease/qiye/mail/rsa/gen",
|
||||
method = {RequestMethod.POST, RequestMethod.GET})
|
||||
@ResponseBody
|
||||
public String metadata(HttpServletRequest request,HttpServletResponse response) {
|
||||
NeteaseRSATool neteaseRSATool =new NeteaseRSATool();
|
||||
neteaseRSATool.genRSAKeyPair();
|
||||
return JsonPretty.getInstance().formatln(neteaseRSATool);
|
||||
}
|
||||
}
|
||||
@@ -17,31 +17,32 @@
|
||||
|
||||
package org.maxkey.authz.exapi.endpoint.adapter;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter;
|
||||
import org.maxkey.crypto.HexUtils;
|
||||
import org.maxkey.crypto.RSAUtils;
|
||||
import org.maxkey.authz.exapi.endpoint.adapter.netease.NeteaseRSATool;
|
||||
import org.maxkey.entity.Accounts;
|
||||
import org.maxkey.entity.ExtraAttr;
|
||||
import org.maxkey.entity.ExtraAttrs;
|
||||
import org.maxkey.entity.apps.Apps;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
|
||||
/**
|
||||
* qiye.163.com
|
||||
* @author shimingxy
|
||||
*
|
||||
*/
|
||||
public class ExtendApiQiye163ExmailAdapter extends AbstractAuthorizeAdapter {
|
||||
final static Logger _logger = LoggerFactory.getLogger(ExtendApiQiye163ExmailAdapter.class);
|
||||
public class ExtendApiNeteaseQiyeMailAdapter extends AbstractAuthorizeAdapter {
|
||||
final static Logger _logger = LoggerFactory.getLogger(ExtendApiNeteaseQiyeMailAdapter.class);
|
||||
//https://entryhz.qiye.163.com
|
||||
static String REDIRECT_URI
|
||||
= "https://entryhz.qiye.163.com/domain/oa/Entry?domain=%s&account_name=%s&time=%s&enc=%s";
|
||||
static String REDIRECT_PARAMETER = "domain=%s&account_name=%s&time=%s&enc=%s&lang=%s";
|
||||
|
||||
static String DEFAULT_REDIRECT_URI ="https://entryhz.qiye.163.com/domain/oa/Entry";
|
||||
|
||||
Accounts account;
|
||||
|
||||
|
||||
@Override
|
||||
public Object generateInfo() {
|
||||
return null;
|
||||
@@ -51,38 +52,43 @@ public class ExtendApiQiye163ExmailAdapter extends AbstractAuthorizeAdapter {
|
||||
public ModelAndView authorize(ModelAndView modelAndView) {
|
||||
|
||||
Apps details=(Apps)app;
|
||||
//extraAttrs from Applications
|
||||
ExtraAttrs extraAttrs=null;
|
||||
if(details.getIsExtendAttr()==1){
|
||||
extraAttrs=new ExtraAttrs(details.getExtendAttr());
|
||||
StringBuffer redirect_uri = new StringBuffer(details.getLoginUrl());
|
||||
if(StringUtils.isNotBlank(redirect_uri)) {
|
||||
if(redirect_uri.indexOf("?")>-1) {
|
||||
redirect_uri.append("").append( REDIRECT_PARAMETER);
|
||||
}else {
|
||||
redirect_uri.append("?").append( REDIRECT_PARAMETER);
|
||||
}
|
||||
}
|
||||
//extraAttrs from App
|
||||
ExtraAttrs extraAttrs=null;
|
||||
if(details.getIsExtendAttr() == 1){
|
||||
extraAttrs = new ExtraAttrs(details.getExtendAttr());
|
||||
for(ExtraAttr attr : extraAttrs.getExtraAttrs()) {
|
||||
redirect_uri.append("&").append(attr.getAttr()).append("=").append(attr.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
String time = System.currentTimeMillis() + "";
|
||||
//域名,请使用企业自己的域名
|
||||
String domain = details.getPrincipal();
|
||||
|
||||
String account_name = this.userInfo.getEmail();
|
||||
String account_name = this.userInfo.getEmail().substring(0, this.userInfo.getEmail().indexOf("@"));
|
||||
|
||||
//String lang = "0";
|
||||
String lang = "0";
|
||||
String src = account_name + domain + time;
|
||||
|
||||
String privateKey = details.getCredentials();
|
||||
String enc = null;
|
||||
try {
|
||||
enc = HexUtils.bytes2HexString(
|
||||
RSAUtils.sign(
|
||||
src.getBytes("UTF-8"),
|
||||
(RSAPrivateKey)RSAUtils.privateKey(HexUtils.hex2Bytes(privateKey)),
|
||||
null)
|
||||
);
|
||||
String loginUrl = String.format(REDIRECT_URI, domain,account_name,time,enc);
|
||||
_logger.debug("LoginUrl {} " , loginUrl);
|
||||
modelAndView.addObject("redirect_uri", loginUrl);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
_logger.error("UnsupportedEncodingException ", e);
|
||||
} catch (Exception e) {
|
||||
_logger.error("Exception ", e);
|
||||
}
|
||||
_logger.debug("Private Key {} " , privateKey);
|
||||
|
||||
String enc = new NeteaseRSATool().generateSHA1withRSASigature(src, privateKey);
|
||||
String loginUrl = String.format(redirect_uri.toString(), domain,account_name,time,enc,lang);
|
||||
|
||||
_logger.debug("LoginUrl {} " , loginUrl);
|
||||
modelAndView.addObject("redirect_uri", loginUrl);
|
||||
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
package org.maxkey.authz.exapi.endpoint.adapter.netease;
|
||||
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Signature;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class NeteaseRSATool {
|
||||
|
||||
final static Logger _logger = LoggerFactory.getLogger(NeteaseRSATool.class);
|
||||
|
||||
private static final char[] bcdLookup = { '0', '1', '2', '3', '4', '5',
|
||||
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
private String description = "1024-bit RSA key";
|
||||
private String priKey = null;
|
||||
private String pubKey = null;
|
||||
|
||||
|
||||
public String bytesToHexStr(byte[] bcd) {
|
||||
StringBuffer s = new StringBuffer(bcd.length * 2);
|
||||
|
||||
for (int i = 0; i < bcd.length; i++) {
|
||||
s.append(bcdLookup[(bcd[i] >>> 4) & 0x0f]);
|
||||
s.append(bcdLookup[bcd[i] & 0x0f]);
|
||||
}
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public byte[] hexStrToBytes(String s) {
|
||||
byte[] bytes;
|
||||
|
||||
bytes = new byte[s.length() / 2];
|
||||
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2),
|
||||
16);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public void genRSAKeyPair() {
|
||||
KeyPairGenerator rsaKeyGen = null;
|
||||
KeyPair rsaKeyPair = null;
|
||||
try {
|
||||
_logger.trace("Generating a pair of RSA key ... ");
|
||||
rsaKeyGen = KeyPairGenerator.getInstance("RSA");
|
||||
SecureRandom random = new SecureRandom();
|
||||
random.setSeed(System.currentTimeMillis());
|
||||
|
||||
rsaKeyGen.initialize(1024, random);
|
||||
|
||||
rsaKeyPair = rsaKeyGen.genKeyPair();
|
||||
PublicKey rsaPublic = rsaKeyPair.getPublic();
|
||||
PrivateKey rsaPrivate = rsaKeyPair.getPrivate();
|
||||
|
||||
pubKey = bytesToHexStr(rsaPublic.getEncoded());
|
||||
priKey = bytesToHexStr(rsaPrivate.getEncoded());
|
||||
_logger.trace("pubKey: {}" , pubKey);
|
||||
_logger.trace("priKey: {}" , priKey);
|
||||
_logger.trace("1024-bit RSA key GENERATED.");
|
||||
} catch (Exception e) {
|
||||
_logger.error("Exception genRSAKeyPair:" + e);
|
||||
}
|
||||
}
|
||||
|
||||
public String generateSHA1withRSASigature(String src, String priKey) {
|
||||
try {
|
||||
byte[] pribyte = hexStrToBytes(priKey.trim());
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
|
||||
KeyFactory fac = KeyFactory.getInstance("RSA");
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec);
|
||||
|
||||
Signature sigEng = Signature.getInstance("SHA1withRSA");
|
||||
sigEng.initSign(privateKey);
|
||||
sigEng.update(src.getBytes());
|
||||
byte[] signature = sigEng.sign();
|
||||
return bytesToHexStr(signature);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String encryptWithPriKey(String src, String priKey) {
|
||||
try {
|
||||
byte[] pribyte = hexStrToBytes(priKey.trim());
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
|
||||
KeyFactory fac = KeyFactory.getInstance("RSA");
|
||||
Key privateKey = fac.generatePrivate(keySpec);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
|
||||
byte[] bytes = src.getBytes();
|
||||
byte[] encodedByteArray = new byte[] {};
|
||||
for (int i = 0; i < bytes.length; i += 102){
|
||||
byte[] subarray = ArrayUtils.subarray(bytes, i, i + 102);
|
||||
byte[] doFinal = cipher.doFinal(subarray);
|
||||
encodedByteArray = ArrayUtils.addAll(encodedByteArray, doFinal);
|
||||
}
|
||||
return bytesToHexStr(encodedByteArray);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean verifySHA1withRSASigature(String sign, String src,
|
||||
String pubKeyStr) {
|
||||
try {
|
||||
|
||||
Signature sigEng = Signature.getInstance("SHA1withRSA");
|
||||
|
||||
byte[] pubbyte = hexStrToBytes(pubKeyStr.trim());
|
||||
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte);
|
||||
KeyFactory fac = KeyFactory.getInstance("RSA");
|
||||
RSAPublicKey pubKey = (RSAPublicKey) fac.generatePublic(keySpec);
|
||||
|
||||
sigEng.initVerify(pubKey);
|
||||
sigEng.update(src.getBytes());
|
||||
|
||||
byte[] sign1 = hexStrToBytes(sign);
|
||||
return sigEng.verify(sign1);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String encryptLongTextWithPriKey(String src, String priKey) {
|
||||
final int ENCRYPT_LENGTH = 117;
|
||||
if (src.length() <= ENCRYPT_LENGTH) {
|
||||
return encryptWithPriKey(src, priKey);
|
||||
}
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int idx = 0;
|
||||
while (idx < src.length()) {
|
||||
int end = idx + ENCRYPT_LENGTH > src.length() ? src.length() : idx + ENCRYPT_LENGTH;
|
||||
String sub = src.substring(idx, end);
|
||||
String encSub = encryptWithPriKey(sub, priKey);
|
||||
sb.append(encSub);
|
||||
idx += ENCRYPT_LENGTH;
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String encryptWithPriKeyWithBase64(String src, String priKey) {
|
||||
try {
|
||||
byte[] pribyte = hexStrToBytes(priKey.trim());
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
|
||||
KeyFactory fac = KeyFactory.getInstance("RSA");
|
||||
Key privateKey = fac.generatePrivate(keySpec);
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||
byte[] signature = cipher.doFinal(src.getBytes());
|
||||
|
||||
return Base64.getEncoder().encodeToString(signature).replaceAll("[^a-zA-Z0-9+/=]", "");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String encryptWithPubKey(String src, String pubKey) {
|
||||
try {
|
||||
byte[] pubbyte = hexStrToBytes(pubKey.trim());
|
||||
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte);
|
||||
|
||||
KeyFactory fac = KeyFactory.getInstance("RSA");
|
||||
Key publicKey = fac.generatePublic(keySpec);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
byte[] signature = cipher.doFinal(src.getBytes());
|
||||
|
||||
return bytesToHexStr(signature);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String decryptWithPriKey(String enc, String priKey) {
|
||||
try {
|
||||
byte[] pribyte = hexStrToBytes(priKey.trim());
|
||||
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
|
||||
KeyFactory fac = KeyFactory.getInstance("RSA");
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) fac
|
||||
.generatePrivate(keySpec);
|
||||
|
||||
// privateKey.getModulus() + privateKey.getPrivateExponent() +
|
||||
// privateKey.getAlgorithm();
|
||||
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
|
||||
byte[] forumcookie = hexStrToBytes(enc);
|
||||
|
||||
byte[] plainText = cipher.doFinal(forumcookie);
|
||||
|
||||
return bytesToHexStr(plainText);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String decryptWithPubKey(String enc, String pubKey) {
|
||||
try {
|
||||
byte[] pubbyte = hexStrToBytes(pubKey.trim());
|
||||
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte);
|
||||
KeyFactory fac = KeyFactory.getInstance("RSA");
|
||||
Key publicKey = fac.generatePublic(keySpec);
|
||||
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||
|
||||
byte[] forumcookie = hexStrToBytes(enc);
|
||||
|
||||
byte[] plainText = cipher.doFinal(forumcookie);
|
||||
|
||||
return new String(plainText);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
e.printStackTrace(System.err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public RSAPrivateKey getPriKey(String priKey) {
|
||||
try {
|
||||
byte[] pribyte = hexStrToBytes(priKey.trim());
|
||||
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
|
||||
KeyFactory fac = KeyFactory.getInstance("RSA");
|
||||
RSAPrivateKey key = (RSAPrivateKey) fac.generatePrivate(keySpec);
|
||||
return key;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public RSAPublicKey getPubKey(String pubKey) {
|
||||
try {
|
||||
byte[] pubbyte = hexStrToBytes(pubKey.trim());
|
||||
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte);
|
||||
KeyFactory fac = KeyFactory.getInstance("RSA");
|
||||
RSAPublicKey key = (RSAPublicKey) fac.generatePublic(keySpec);
|
||||
return key;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getPri() {
|
||||
return priKey;
|
||||
}
|
||||
|
||||
public void setPri(String pri) {
|
||||
this.priKey = pri;
|
||||
}
|
||||
|
||||
public String getPub() {
|
||||
return pubKey;
|
||||
}
|
||||
|
||||
public void setPub(String pub) {
|
||||
this.pubKey = pub;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user