gpt4 book ai didi

java - 根据 SAML 请求创建 SAML 响应

转载 作者:行者123 更新时间:2023-11-29 06:33:27 25 4
gpt4 key购买 nike

我开发了一个 Java 网络应用程序,我想实现 SAML。这些是我认为实现 SAML 的正确步骤。

  1. 服务提供商(SP,在本例中为我的应用程序)向 IdP 发送 SAML 身份验证请求。
  2. 然后 IdP 对其进行验证并创建 SAML 响应断言并使用证书对其进行签名,然后发送回 SP。
  3. 然后 SP 使用 keystore 中证书的公钥对其进行验证,并在此基础上进一步进行。

我有一个示例代码,我可以创建 SAML 请求以及类似的请求

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="_c7b796f4-bc16-4fcc-8c1d-36befffc39c2" Version="2.0"
IssueInstant="2014-10-30T11:21:08Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
AssertionConsumerServiceURL="http://localhost:8080/mywebapp/consume.jsp">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:8080/mywebapp
</saml:Issuer>
<samlp:NameIDPolicy
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified"
AllowCreate="true"></samlp:NameIDPolicy>
<samlp:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
</samlp:AuthnRequest>

我可以对其进行编码并发送给 IdP。

我想创建示例 Java 代码来获取此 SAML 请求,然后创建 SAML 响应。如何解码请求并验证它并创建响应?我需要用证书签署 saml 响应吗?然后发回SP?

谢谢。

最佳答案

虽然这是一篇旧帖子,但我添加了我认为有用的示例代码和引用资料。

SAMLResponse = hreq.getParameter("SAMLResponse");
InputSource inputSource = new InputSource(new StringReader(SAMLResponse));
SAMLReader samlReader = new SAMLReader();
response2 = org.opensaml.saml2.core.Response)samlReader.readFromFile(inputSource);

现在验证数字签名:

org.opensaml.saml2.core.Response response2 = (org.opensaml.saml2.core.Response)samlReader.readFromFile(inputSource);  
//To fetch the digital signature from the response.
Signature signature = response2.getSignature();
X509Certificate certificate = (X509Certificate) keyStore.getCertificate(domainName);
//pull out the public key part of the certificate into a KeySpec
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(certificate.getPublicKey().getEncoded());
//get KeyFactory object that creates key objects, specifying RSA - java.security.KeyFactory
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//generate public key to validate signatures
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
//we have the public key
BasicX509Credential publicCredential = new BasicX509Credential();
//add public key value
publicCredential.setPublicKey(publicKey);
//create SignatureValidator
SignatureValidator signatureValidator = new SignatureValidator(publicCredential);
//try to validate
try{
signatureValidator.validate(signature);
catch(Exception e){
//
}

现在获取断言图:

samlDetailsMap = setSAMLDetails(response2);

在上面的逻辑中,使用下面的私有(private)方法来拉取所有断言属性。最后,您将获得发送给您的所有字段的 map 。

 private Map<String, String> setSAMLDetails(org.opensaml.saml2.core.Response  response2){
Map<String, String> samlDetailsMap = new HashMap<String, String>();
try {
List<Assertion> assertions = response2.getAssertions();
LOGGER.error("No of assertions : "+assertions.size());
for(Assertion assertion:assertions){
List<AttributeStatement> attributeStatements = assertion.getAttributeStatements();
for(AttributeStatement attributeStatement: attributeStatements){
List<Attribute> attributes = attributeStatement.getAttributes();
for(Attribute attribute: attributes){
String name = attribute.getName();
List<XMLObject> attributes1 = attribute.getAttributeValues();
for(XMLObject xmlObject : attributes1){
if(xmlObject instanceof XSString){
samlDetailsMap.put(name, ((XSString) xmlObject).getValue());
LOGGER.error("Name is : "+name+" value is : "+((XSString) xmlObject).getValue());
}else if(xmlObject instanceof XSAnyImpl){
String value = ((XSAnyImpl) xmlObject).getTextContent();

samlDetailsMap.put(name, value);

}
}
}
}
}
} catch (Exception e) {
LOGGER.error("Exception occurred while setting the saml details");
}
LOGGER.error("Exiting from setSAMLDetails method");
return samlDetailsMap;
}

添加新类 SAMLReader 如下:

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.opensaml.DefaultBootstrap;
import org.opensaml.xml.Configuration;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.io.UnmarshallingException;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class SAMLReader {

private static DocumentBuilder builder;

static{
try{
DefaultBootstrap.bootstrap ();
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance ();
factory.setNamespaceAware (true);
builder = factory.newDocumentBuilder ();
}catch (Exception ex){
ex.printStackTrace ();
}
}



/**
*
* @param filename
* @return
* @throws IOException
* @throws UnmarshallingException
* @throws SAXException
*/
public XMLObject readFromFile (String filename)
throws IOException, UnmarshallingException, SAXException{
return fromElement (builder.parse (filename).getDocumentElement ());
}
/**
*
* @param is
* @return
* @throws IOException
* @throws UnmarshallingException
* @throws SAXException
*/
public XMLObject readFromFile (InputStream is)
throws IOException, UnmarshallingException, SAXException{
return fromElement (builder.parse (is).getDocumentElement ());
}
/**
*
* @param is
* @return
* @throws IOException
* @throws UnmarshallingException
* @throws SAXException
*/
public XMLObject readFromFile (InputSource is)
throws IOException, UnmarshallingException, SAXException{
return fromElement (builder.parse (is).getDocumentElement ());
}

/**
*
* @param element
* @return
* @throws IOException
* @throws UnmarshallingException
* @throws SAXException
*/
public static XMLObject fromElement (Element element)
throws IOException, UnmarshallingException, SAXException{
return Configuration.getUnmarshallerFactory ()
.getUnmarshaller (element).unmarshall (element);
}

关于java - 根据 SAML 请求创建 SAML 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26647664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com