当前位置: 首页 > 工具软件 > java-saml > 使用案例 >

saml2.0 java 例子_saml2.0(主要是idp端开发)

陆城
2023-12-01

附上大佬文章:

https://www.jianshu.com/p/d041935641b4

https://www.jianshu.com/p/6f61fa7be0b6

https://www.jianshu.com/p/6c72408fa480

看了大佬的文章和demo基本能搞出来一套本地可用的saml2.0。

在我开发过程中主要是我们作为IDP,做统一登录后发送给第三方SP做免登录。

主要就几个过程:

1.SP通过发送SAML AuthnRequest到IDP,来请求鉴别用户身份

2.IDP验证身份,然后通过SAML产物响应(SAML Artifact Response)发送回SP

其中几个点:

1.记得初始化SAML,否则会出现NPE

2.如果有需要POST请求,可通过简单form表单自动提交

window.οnlοad= function(){

document.getElementById('myForm').submit();

}

3.responseValue是response的base64加密

4.opensaml 3 默认加密算法是sha256,如果需要sha1可能需要降低到opensaml 2

5.opensaml 3 采用的是分开打包maven的方式,需要引入很多个模块,参考大佬文章,opensaml 2 是整体maven直接引入即可。例如:

org.opensaml

opensaml

2.6.4

ch.qos.logback

logback-core

1.1.7

ch.qos.logback

logback-classic

1.1.7

commons-logging

commons-logging

1.2

org.opensaml

xmltooling

1.4.4

6.断言可以对assertion做,也可以对整个response做签名。根据需要自选。

这个签名主要是idp端用证书私钥做签名,sp端用公钥做验签。

我采用的是pfx的方式,把文件流读入,然后获取私钥,公钥。做签名

public class CertificateUtils {

private static final Logger LOGGER = LoggerFactory.getLogger(CertificateUtils.class);

private static final String PFX_CERT_FILE_SUFFIX = ".pfx";

public static X509CertificateWrapper getCertByFile(String fileName, String pfxOpenPwd) {

if (isPfxCertFileName(fileName)) {

return getPfxCert(fileName, pfxOpenPwd);

} else {

LOGGER.error("get pfx certificate info failed");

throw new Exception(xxx);

}

}

private static boolean isPfxCertFileName(String fileName) {

return fileName.endsWith(PFX_CERT_FILE_SUFFIX);

}

private static X509CertificateWrapper getPfxCert(String fileName, String pfxOpenPwd){

Assert.hasText(pfxOpenPwd, "pfx file open pwd missing");

InputStream fileInputStream = getResourceAsStreamByFileName(fileName);

return getPfxCertificate(fileInputStream, pfxOpenPwd);

}

//fileName 相对路径 比如resource/cert/xxx.pfx fileName="cert/xxx.pfx"

private static InputStream getResourceAsStreamByFileName(String fileName) {

return Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);

}

private static char[] getFileOpenPwdChars(String fileOpenPwd) {

if (StringUtils.isBlank(fileOpenPwd) || StringUtils.isBlank(StringUtils.trim(fileOpenPwd))) {

return null;

}

return fileOpenPwd.toCharArray();

}

private static X509CertificateWrapper getPfxCertificate(InputStream inputStream, String pfxOpenPwd){

X509CertificateWrapper x509CertificateWrapper = new X509CertificateWrapper(null, null) ;

try {

KeyStore ks = KeyStore.getInstance("PKCS12");

char[] nPassword = getFileOpenPwdChars(pfxOpenPwd);

ks.load(inputStream, nPassword);

String keyAlias = getKeyAlias(ks);

PrivateKey privateKey = (PrivateKey) ks.getKey(keyAlias, nPassword);

X509Certificate cert = (X509Certificate) ks.getCertificate(keyAlias);

String certStr = convertCertObj2certStr(cert);

x509CertificateWrapper.setX509Certificate(cert);

x509CertificateWrapper.setContent(certStr);

x509CertificateWrapper.setPrivateKey(privateKey);

} catch (KeyStoreException e) {

throw new RuntimeException("Error occurred when read the pfx file stream", e);

} catch (IOException e) {

throw new RuntimeException("Error occurred when read the pfx file stream", e);

} catch (NoSuchAlgorithmException e) {

throw new RuntimeException("Error occurred when read the pfx file stream", e);

} catch (CertificateException e) {

throw new RuntimeException("Error occurred when read the pfx file stream", e);

} catch (UnrecoverableKeyException e) {

throw new RuntimeException("Error occurred when read the pfx file stream", e);

} finally {

try {

inputStream.close();

} catch (IOException e) {

throw new RuntimeException("Error occurred when read the pfx file stream", e);

}

}

return x509CertificateWrapper;

}

private static String getKeyAlias(KeyStore ks) throws KeyStoreException {

Enumeration aliases = ks.aliases();

// we are read just one certificate.

if (aliases.hasMoreElements()) {

return aliases.nextElement();

}

return null;

}

public static String convertCertObj2certStr(Certificate certificate) {

if (certificate == null) {

return "";

}

try {

String certStr = Base64.getEncoder().encodeToString(certificate.getEncoded());

return certStr;

} catch (CertificateEncodingException e) {

LOGGER.error("convertCertObj2certStr error, CertificateEncodingException {}", e);

return "";

}

}

public class X509CertificateWrapper {

private X509Certificate x509Certificate;

private PrivateKey privateKey;

private String content;

public X509CertificateWrapper(X509Certificate x509Certificate, String content) {

this.content = content;

this.x509Certificate = x509Certificate;

}

public X509Certificate getX509Certificate() {

return x509Certificate;

}

public void setX509Certificate(X509Certificate x509Certificate) {

this.x509Certificate = x509Certificate;

}

public String getContent() {

return content;

}

public PrivateKey getPrivateKey() {

return privateKey;

}

public void setPrivateKey(PrivateKey privateKey) {

this.privateKey = privateKey;

}

public void setContent(String content) {

this.content = content;

}

}

 类似资料: