• cas4.0集成 saml2协议如何针对断言进行签名?


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 gy坏坏 2024-04-03 16:20 采纳率: 0% 浏览 1 首页/ 编程语言 / cas4.0集成 saml2协议如何针对断言进行签名? java cas4.0集成 saml2协议如何针对断言进行签名? MyGoogleAccountsService.java ```java package com.gilight.cas.authorize.saml2; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import org.jasig.cas.authentication.principal.AbstractWebApplicationService; import org.jasig.cas.authentication.principal.Response; import org.jasig.cas.support.saml.util.SamlUtils; import org.jdom.Document; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; import java.util.zip.DataFormatException; import java.util.zip.Deflater; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; public class MyGoogleAccountsService extends AbstractWebApplicationService { private static final long serialVersionUID = 6678711809842282833L; private static SecureRandom RANDOM_GENERATOR = new SecureRandom(); private static final char[] CHAR_MAPPINGS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'}; private static final String CONST_PARAM_SERVICE = "SAMLRequest"; private static final String CONST_RELAY_STATE = "RelayState"; private static final String TEMPLATE_SAML_RESPONSE = "\" IssueInstant=\"\" Version=\"2.0\"" + " xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\"" + " xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"" + " Destination=\"https://login.microsoftonline.com/login.srf\"" + " xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\">" + "" + "" + "" + "\"" + " IssueInstant=\"\" Version=\"2.0\"" + " xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"" // + " xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\"" + ">" + "https://365.sias.edu.cn/cas" + "" // + "" + "" + "" + "" + "" + "\" NotOnOrAfter=\"\" InResponseTo=\"\" />" + "" + "" + "\"" + " NotOnOrAfter=\"\">" + "" + "" + "" + "" // 人员属性 + "" + "" + "" + "\">" + "" + "" + "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" + "" + "" + "" + ""; private final String relayState; private final PublicKey publicKey; private final PrivateKey privateKey; private final String requestId; private final String alternateUserName; private static X509Certificate x509; protected MyGoogleAccountsService(final String id, final String relayState, final String requestId, final PrivateKey privateKey, final PublicKey publicKey, final String alternateUserName) { this(id, id, null, relayState, requestId, privateKey, publicKey, alternateUserName); } protected MyGoogleAccountsService(final String id, final String originalUrl, final String artifactId, final String relayState, final String requestId, final PrivateKey privateKey, final PublicKey publicKey, final String alternateUserName) { super(id, originalUrl, artifactId); this.relayState = relayState; this.privateKey = privateKey; this.publicKey = publicKey; this.requestId = requestId; this.alternateUserName = alternateUserName; } public static MyGoogleAccountsService createServiceFrom( final HttpServletRequest request, final PrivateKey privateKey, final PublicKey publicKey, final String alternateUserName, X509Certificate x509Certificate) { x509 = x509Certificate; final String relayState = request.getParameter(CONST_RELAY_STATE); final String xmlRequest = decodeAuthnRequestXML(request.getParameter(CONST_PARAM_SERVICE)); if (!StringUtils.hasText(xmlRequest)) { return null; } final Document document = SamlUtils.constructDocumentFromXmlString(xmlRequest); if (document == null) { return null; } // 获取sp url String assertionConsumerServiceUrl = document.getRootElement().getAttributeValue("AssertionConsumerServiceURL"); if(null == assertionConsumerServiceUrl){ assertionConsumerServiceUrl = request.getHeader("Referer"); } if(null == assertionConsumerServiceUrl){ assertionConsumerServiceUrl = request.getHeader("Origin"); } String requestId = document.getRootElement().getAttributeValue("ID"); if(null == requestId ){ requestId = "1"; } return new MyGoogleAccountsService(assertionConsumerServiceUrl, relayState, requestId, privateKey, publicKey, alternateUserName); } @Override public Response getResponse(final String ticketId) { final Map parameters = new HashMap(); String uuid = createID(); final String samlResponse = constructSamlResponse(uuid); String signedResponse = MySamlUtils.signSamlResponse(samlResponse, this.privateKey, this.publicKey, x509); parameters.put("SAMLResponse", new String(Base64.encodeBase64(signedResponse.getBytes()))); parameters.put("RelayState", this.relayState); return Response.getPostResponse(getOriginalUrl(), parameters); } /** * Return true if the service is already logged out. * * @return true if the service is already logged out. */ @Override public boolean isLoggedOutAlready() { return true; } private String constructSamlResponse(String uuid) { String samlResponse = TEMPLATE_SAML_RESPONSE; final Calendar c = Calendar.getInstance(); c.setTime(new Date()); c.add(Calendar.YEAR, 1); String userId; if (this.alternateUserName == null) { userId = getPrincipal().getId(); } else { final String attributeValue = (String) getPrincipal().getAttributes().get(this.alternateUserName); if (attributeValue == null) { userId = getPrincipal().getId(); } else { userId = attributeValue; } } samlResponse = samlResponse.replace("", userId ); samlResponse = samlResponse.replace("", createID()); // samlResponse = samlResponse.replace("", SamlDateUtils.getCurrentDateAndTime()); // samlResponse = samlResponse.replace("", SamlDateUtils.getCurrentDateAndTime()); // samlResponse = samlResponse.replaceAll("", SamlDateUtils.getFormattedDateAndTime(c.getTime())); samlResponse = samlResponse.replace("", getCurrentDateAndTime()); samlResponse = samlResponse.replace("", getCurrentDateAndTime()); samlResponse = samlResponse.replaceAll("", getFormattedDateAndTime(c.getTime())); samlResponse = samlResponse.replace("", uuid); samlResponse = samlResponse.replaceAll("", getId()); samlResponse = samlResponse.replace("", this.requestId); // 人员属性 Map attributeMap = getPrincipal().getAttributes(); // 邮箱 if(null != attributeMap && attributeMap.size() > 0 ){ String mailbox = null != attributeMap.get("mailbox") ? (String)attributeMap.get("mailbox") : null; if(null != mailbox){ samlResponse = samlResponse.replace("", mailbox); } } return samlResponse; } private static String createID() { final byte[] bytes = new byte[20]; // 160 bits RANDOM_GENERATOR.nextBytes(bytes); final char[] chars = new char[40]; for (int i = 0; i < bytes.length; i++) { int left = bytes[i] >> 4 & 0x0f; int right = bytes[i] & 0x0f; chars[i * 2] = CHAR_MAPPINGS[left]; chars[i * 2 + 1] = CHAR_MAPPINGS[right]; } return String.valueOf(chars); } private static String decodeAuthnRequestXML( final String encodedRequestXmlString) { if (encodedRequestXmlString == null) { return null; } // final byte[] decodedBytes = base64Decode(encodedRequestXmlString); final byte[] decodedBytes = compressString(encodedRequestXmlString); if (decodedBytes == null) { return null; } final String inflated = inflate(decodedBytes); if (inflated != null) { return inflated; } return zlibDeflate(decodedBytes); } private static String zlibDeflate(final byte[] bytes) { final ByteArrayInputStream bais = new ByteArrayInputStream(bytes); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final InflaterInputStream iis = new InflaterInputStream(bais); final byte[] buf = new byte[1024]; try { int count = iis.read(buf); while (count != -1) { baos.write(buf, 0, count); count = iis.read(buf); } return new String(baos.toByteArray()); } catch (final Exception e) { return null; } finally { IOUtils.closeQuietly(iis); } } private static byte[] base64Decode(final String xml) { try { final byte[] xmlBytes = xml.getBytes("UTF-8"); return Base64.decodeBase64(xmlBytes); } catch (final Exception e) { return null; } } private static String inflate(final byte[] bytes) { final Inflater inflater = new Inflater(true); final byte[] xmlMessageBytes = new byte[10000]; final byte[] extendedBytes = new byte[bytes.length + 1]; System.arraycopy(bytes, 0, extendedBytes, 0, bytes.length); extendedBytes[bytes.length] = 0; inflater.setInput(extendedBytes); try { final int resultLength = inflater.inflate(xmlMessageBytes); inflater.end(); if (!inflater.finished()) { throw new RuntimeException("buffer not large enough."); } inflater.end(); return new String(xmlMessageBytes, 0, resultLength, "UTF-8"); } catch (final DataFormatException e) { return null; } catch (final UnsupportedEncodingException e) { throw new RuntimeException("Cannot find encoding: UTF-8", e); } } public static byte[] compressString(String input) { try { if(isBase64String(input)){ input = new String(Base64.decodeBase64(input)); } byte[] inputData = input.getBytes("UTF-8"); Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true); deflater.setInput(inputData); deflater.finish(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(inputData.length); byte[] buffer = new byte[2048]; while (!deflater.finished()) { int count = deflater.deflate(buffer); outputStream.write(buffer, 0, count); } deflater.end(); return outputStream.toByteArray(); } catch (Exception e) { // TODO: handle exception } return null; } /** * 判断是否为base64 * @param str * @return * @author gy */ public static boolean isBase64String(String str) { try { byte[] decodedBytes = Base64.decodeBase64(str); String encodedString = Base64.encodeBase64String(decodedBytes); return str.equals(encodedString); } catch (IllegalArgumentException e) { return false; } } public static String getCurrentDateAndTime() { return getFormattedDateAndTime(new Date()); } public static String getFormattedDateAndTime(final Date date) { final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); return dateFormat.format(date); } } MySamlUtils.java ```java package com.gilight.cas.authorize.saml2; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.DOMBuilder; import org.jdom.input.SAXBuilder; import org.jdom.output.DOMOutputter; import org.jdom.output.XMLOutputter; import org.w3c.dom.Node; import org.xml.sax.InputSource; import javax.xml.crypto.dsig.*; import javax.xml.crypto.dsig.dom.DOMSignContext; import javax.xml.crypto.dsig.keyinfo.KeyInfo; import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; import javax.xml.crypto.dsig.spec.TransformParameterSpec; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.ByteArrayInputStream; import java.io.StringReader; import java.io.StringWriter; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * saml工具 * @ClassName: MySamlUtils * @author: gy * @date: 2024年4月1日 */ public class MySamlUtils { private static final String JSR_105_PROVIDER = "org.jcp.xml.dsig.internal.dom.XMLDSigRI"; private static final String SAML_PROTOCOL_NS_URI_V20 = "urn:oasis:names:tc:SAML:2.0:protocol"; /** * The constructor is intentionally marked as private. */ private MySamlUtils() { // nothing to do } public static String signSamlResponse(final String samlResponse, final PrivateKey privateKey, final PublicKey publicKey, X509Certificate x509Certificate) { Document doc = constructDocumentFromXmlString(samlResponse); if (doc != null) { // 获取断言 Element element = (Element) doc.getRootElement().getContent().get(1); // 断言签名 final Element signedElement = signSamlElement(element, privateKey, publicKey, x509Certificate); // doc.setRootElement((Element) signedElement.detach()); // return new XMLOutputter().outputString(doc); // final Element signedElement = signSamlElement(doc.getRootElement(), privateKey, publicKey, x509Certificate); //element.addContent((Element)signedElement.getContent().get(2)); // 1.断言签名结果转字符串 String signed = getElementXML(toDom2(signedElement)).replace("", ""); System.out.println(signed); // TODO 2.通过samlResponse StringBuilder sb = new StringBuilder(); sb.append(samlResponse.substring(0,samlResponse.indexOf("") + 18)); String xml = sb.toString(); return xml; } throw new RuntimeException("Error signing SAML Response: Null document"); } public static Document constructDocumentFromXmlString(final String xmlString) { try { final SAXBuilder builder = new SAXBuilder(); builder.setFeature("http://xml.org/sax/features/external-general-entities", false); builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); return builder.build(new ByteArrayInputStream(xmlString.getBytes())); } catch (final Exception e) { return null; } } private static Element signSamlElement(final Element element, final PrivateKey privKey, final PublicKey pubKey, X509Certificate x509Certificate) { try { final String providerName = System.getProperty("jsr105Provider", JSR_105_PROVIDER); final XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM", (Provider) Class.forName(providerName).newInstance()); List envelopedTransform = new ArrayList(); envelopedTransform.add(sigFactory.newTransform(Transform.ENVELOPED,(TransformParameterSpec) null)); envelopedTransform.add(sigFactory.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#",(TransformParameterSpec) null)); // Element element1 = (Element) element.getContent().get(1); // System.out.println(getElementXML(toDom(element1))); // final Reference ref = sigFactory.newReference("#" + element1.getAttribute("ID").getValue(), sigFactory.newDigestMethod(DigestMethod.SHA256, null), envelopedTransform, null, null); final Reference ref = sigFactory.newReference("", sigFactory.newDigestMethod(DigestMethod.SHA256, null), envelopedTransform, null, null); // final Reference ref = sigFactory.newReference("" , sigFactory.newDigestMethod(DigestMethod.SHA1, null), envelopedTransform, null, null); // Create the SignatureMethod based on the type of key SignatureMethod signatureMethod; if (pubKey instanceof DSAPublicKey) { signatureMethod = sigFactory.newSignatureMethod(SignatureMethod.DSA_SHA1, null); } else if (pubKey instanceof RSAPublicKey) { signatureMethod = sigFactory.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null); // signatureMethod = sigFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null); } else { throw new RuntimeException("Error signing SAML element: Unsupported type of key"); } final CanonicalizationMethod canonicalizationMethod = sigFactory.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null); // 创建签名信息 final SignedInfo signedInfo = sigFactory.newSignedInfo(canonicalizationMethod, signatureMethod, Collections.singletonList(ref)); //创建包含DSA或RSA PublicKey的KeyValue final KeyInfoFactory keyInfoFactory = sigFactory.getKeyInfoFactory(); // 使用 KeyInfoFactory 创建 KeyInfo 对象,并添加 X509Data KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(keyInfoFactory.newX509Data(Collections.singletonList(x509Certificate)))); // 在指定位置进行数字签名 // org.w3c.dom.Element w3cElement = toDom(element); org.w3c.dom.Element w3cElement = toDom2(element); System.err.println("----1:" + getElementXML(w3cElement)); // 创建签名内容对象privKey私钥, w3cElement 待签名xml DOMSignContext signContext = new DOMSignContext(privKey, w3cElement); // xml签名对象signedInfo签名信息, keyInfo公钥相关信息 XMLSignature signature = sigFactory.newXMLSignature(signedInfo, keyInfo); // 使用提供的私钥对指定的XML元素进行数字签名,将签名结果附加到XML文档中 signature.sign(signContext); System.err.println("----2:" + getElementXML(w3cElement)); return toJdom(w3cElement); } catch (final Exception e) { throw new RuntimeException("Error signing SAML element: " + e.getMessage(), e); } } private static Node getXmlSignatureInsertLocation(final org.w3c.dom.Element elem) { Node insertLocation = null; org.w3c.dom.NodeList nodeList = elem.getElementsByTagNameNS(SAML_PROTOCOL_NS_URI_V20, "Extensions"); if (nodeList.getLength() != 0) { insertLocation = nodeList.item(nodeList.getLength() - 1); } else { nodeList = elem.getElementsByTagNameNS(SAML_PROTOCOL_NS_URI_V20, "Status"); insertLocation = nodeList.item(nodeList.getLength() - 1); } return insertLocation; } private static org.w3c.dom.Element toDom2(final Element element) { try { // 克隆要转换的元素 Element clonedElement = (Element) element.clone(); // 将克隆后的元素添加到新的 org.jdom.Document 中 Document jdomDocument = new Document(clonedElement); // 使用 DOMOutputter 进行转换 DOMOutputter domOutputter = new DOMOutputter(); org.w3c.dom.Document w3cDocument = domOutputter.output(jdomDocument); // 从 org.w3c.dom.Document 获取 org.w3c.dom.Element return w3cDocument.getDocumentElement(); }catch (Exception e){ return null; } } private static org.w3c.dom.Element toDom(final Element element) { return toDom(element.getDocument()).getDocumentElement(); } private static org.w3c.dom.Document toDom(final Document doc) { try { final XMLOutputter xmlOutputter = new XMLOutputter(); final StringWriter elemStrWriter = new StringWriter(); xmlOutputter.output(doc, elemStrWriter); final byte[] xmlBytes = elemStrWriter.toString().getBytes(); final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); return dbf.newDocumentBuilder().parse(new ByteArrayInputStream(xmlBytes)); } catch (final Exception e) { return null; } } private static Element toJdom(final org.w3c.dom.Element e) { return new DOMBuilder().build(e); } /** * 仅测试 * @param w3cElement * @return * @author gy */ public static String getElementXML(org.w3c.dom.Element w3cElement) { try { // 创建转换器工厂 TransformerFactory transformerFactory = TransformerFactory.newInstance(); // 创建转换器 Transformer transformer = transformerFactory.newTransformer(); // 将DOMSource包装W3C Element DOMSource domSource = new DOMSource(w3cElement); // 创建StringWriter来保存XML内容 StringWriter writer = new StringWriter(); // 将DOMSource转换为StreamResult,输出到StringWriter StreamResult result = new StreamResult(writer); // 执行转换 transformer.transform(domSource, result); // 返回XML字符串 return writer.toString(); } catch (Exception e) { e.printStackTrace(); return null; } } /** * xml转element * @param xmlString * @return * @author gy */ public static Element createElement(String xmlString){ try { // 创建DocumentBuilder DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); // 将XML字符串转换为InputSource InputSource is = new InputSource(new StringReader(xmlString)); // 解析XML并获取Document对象 Document doc = (Document) builder.parse(is); // 获取Document的DocumentElement,即根元素 Element rootElement = doc.getRootElement(); return rootElement; } catch (Exception e) { e.printStackTrace(); return null; } } /** * xml转element * @param xmlString * @return * @author gy */ public static Element createElement2(String xmlString){ try { SAXBuilder builder = new SAXBuilder(); Document jdomDocument = builder.build(new StringReader(xmlString)); Element rootElement = jdomDocument.getRootElement(); return rootElement; } catch (Exception e) { e.printStackTrace(); return null; } } } 展开全部 收起 写回答 好问题 0 提建议 追加酬金 关注问题 微信扫一扫 点击复制链接 分享 邀请回答 编辑 收藏 删除 结题 收藏 举报 追加酬金 (90%的用户在追加酬金后获得了解决方案) 当前问题酬金 ¥ 0 (可追加 ¥500) ¥ 15¥ 20¥ 50¥ 100¥ 200 支付方式 扫码支付 二维码出错 点击刷新 支付金额 15 元 提供问题酬金的用户不参与问题酬金结算和分配 支付即为同意 《付费问题酬金结算规则》 结题 再想想 删除 再等等

    2条回答 默认 最新

    • 码农阿豪 Java领域优质创作者 2024-04-03 16:25
      关注
      让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
      该问题需要进一步了解Cas4.0的SAML2协议集成以及对断言进行签名的方法。 对于该问题,可以按照以下步骤回答:
      1. Cas4.0集成SAML2协议需要进行哪些配置? 答:Cas4.0集成SAML2协议需要在cas.properties文件中配置一些基本信息,例如: cas.samlKeystore.file=/path/to/keystore cas.samlKeystore.password=password cas.samlKeystore.privateKeyPassword=password cas.samlIdentityProvider.entityId=https://example.com cas.samlIdentityProvider.metadata.location=/path/to/idp-metadata.xml 其中,samlKeystore为Keystore文件的位置,包含了私钥和公钥,samlIdentityProvider为身份提供者的基本信息。
      2. 如何对断言进行签名? 答:对于SAML2协议断言的签名,可以按照以下步骤进行: (1) 配置Keystore文件,生成公钥和私钥。 (2) 在CAS配置文件中配置MetadataSigningCriterion,用于验证元数据和签名。 (3) 在生成的SAML响应中,使用私钥对断言部分进行签名。签名部分需要包括ID、IssueInstant、Issuer、NameID、Attributes等内容。 示例代码如下: PublicKey publicKey = (PublicKey) casSamlClient.getMetadataResolver().resolveSingle(new CriteriaSet(new EntityIdCriterion(IDP_ENTITY_ID)), "idp.crt"); PrivateKey privateKey = (PrivateKey) metadataResolver.getEntityDescriptor(SP_ENTITY_ID).getSPSSODescriptor("urn:oasis:names:tc:SAML:2.0:protocol").getKeyDescriptors(KeyDescriptor.DEFAULT_ELEMENT_NAME).get(0).getKeyInfo().getPrivateKey(); Assertion assertion = new AssertionBuilder().buildObject(); // 构建断言部分 assertion.setID("" + UUID.randomUUID().toString()); assertion.setIssueInstant(new DateTime()); assertion.setIssuer(new IssuerBuilder().buildObject()); assertion.getIssuer().setValue(IDP_ENTITY_ID); assertion.getIssuer().setFormat(NameIDType.ENTITY); assertion.setSubject(new SubjectBuilder().buildObject()); assertion.getSubject().setNameID(new NameIDBuilder().buildObject()); assertion.getSubject().getNameID().setValue(USERNAME_STRING); assertion.getSubject().getNameID().setFormat(NameIDType.PERSISTENT); assertion.setConditions(new ConditionsBuilder().buildObject()); assertion.getConditions().setNotBefore(new DateTime().minusMinutes(5)); assertion.getConditions().setNotOnOrAfter(new DateTime().plusMinutes(5)); assertion.setAuthnStatement(new AuthnStatementBuilder().buildObject()); assertion.getAuthnStatement().setAuthnInstant(new DateTime().minusMinutes(10)); assertion.getAuthnStatement().setSessionIndex("" + UUID.randomUUID().toString()); // 签名断言 Signer.signObject(assertion); // 将签名后的断言部分转换成字符串,添加到SAML响应中 StringWriter writer = new StringWriter(); Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(assertion); marshaller.marshal(assertion, writer); String assertionString = writer.toString(); String samlResponse = TEMPLATE_SAML_RESPONSE.replace("", assertion.getID()).replace("", USERNAME_STRING).replace("", new DateTime().toString()).replace("", "_" + UUID.randomUUID().toString()) + assertionString + ""; // 将SAML响应进行压缩 ByteArrayOutputStream baos = new ByteArrayOutputStream(); Deflater compressor = new Deflater(Deflater.DEFLATED, true); DeflaterOutputStream dos = new DeflaterOutputStream(baos, compressor); dos.write(samlResponse.getBytes("UTF-8")); dos.finish(); dos.close(); samlResponse = new String(Base64.encodeBase64(baos.toByteArray())); 可以看到,代码中使用了Signer.signObject方法进行断言签名,并将签名后的断言部分添加到了SAML响应中。另外,还使用了Deflater进行压缩,并使用Base64编码将响应部分转换成字符串。

      展开全部

      评论
    • GISer Liu 2024-04-03 16:42
      关注

      该回答引用自GPT-3.5,由博主GISer Liu编写:

      对于CAS 4.0集成SAML 2协议如何针对断言进行签名的问题,您可以按照以下步骤操作:

      1. 创建SAML Response:

      首先,您需要创建一个符合SAML 2协议的响应XML。在模板中,您可以看到有一个``` samlp:Response

      ```元素,其中包含了响应的相关信息,如ID、IssueInstant等。

      2. 签名SAML Response:

      接下来,您需要使用私钥对SAML Response进行签名。在您的MyGoogleAccountsService类中,可以看到有一个getResponse方法,该方法负责构建SAML Response并对其进行签名。

      3. 编码并发送响应:

      最后,将签名后的SAML Response进行Base64编码,并将其放入HTTP POST请求中的SAMLResponse参数中,同时将RelayState参数也添加到请求中。这样,您就可以将签名后的SAML Response发送给服务提供商(SP)。
      以上是整个流程的基本步骤,您可以根据您的具体需求和环境进行相应的调整和优化。如果您需要进一步的帮助或有其他问题,请随时告诉我。

      如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

      评论
    编辑
    预览

    报告相同问题?

  • 相关阅读:
    【黑马头条之项目部署_持续集成Jenkins】
    Java基础--阳光总在风雨后,请相信彩虹
    [附源码]JAVA毕业设计霍山石斛网站(系统+LW)
    CCF区块链会议--Middleware 2024 截止5.24 附录用率
    jq——基础操作——jq操作回顾(都忘光了。。。)
    SpringBoot2.7.14整合redis7
    2021 年河南省中等职业教育技能大赛“网络安全”项目比赛任务书解析教程
    Flutter-实现头像叠加动画效果
    R语言——taxize(第四部分)
    对接新浪股票交易接口api需要注意哪些细节 ?
  • 原文地址:https://ask.csdn.net/questions/8083243