How to add a signature as a GET request parameter using Java and OpenSaml?
Alexey
strolling.code at gmail.com
Mon Sep 1 02:31:29 EDT 2014
Hi,
I should get a GET authentication request with a certain set of parameters:
> "https://domain_name_of_idp_here/idp/profile/SAML2/Redirect/SSO?" +
> "SAMLRequest=" + SAMLRequest + "&SigAlg=" + SigAlg + "&Signature=" +
> Signature
Thus, I'm interested in the parameters:
*SAMLRequest
SigAlg
Signature*
When I used OIOSAML
<https://svn.softwareborsen.dk/oiosaml.java/sp/trunk/webapp/> , all these
parts of the request formed automatically, but it was not possible to
flexibly manage them and get full control.
So I decided to write my sP- based Web SSO by using OpenSAML 2.4.1
<http://shibboleth.net/downloads/java-opensaml/2.4.1/>
Consider how to create SAMLRequest. My idP requires that sP- AuthnRequest
requests come in this format:
> <?xml version="1.0" encoding="UTF-8"?>
> <saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
> AssertionConsumerServiceURL=
> "https://ip_of_my_sp_here/oiosaml/saml/SAMLAssertionConsumer"
>
> Destination="https://domain_name_of_idp_here/idp/profile/SAML2/Redirect/SSO"
> ForceAuthn="false"
> ID="_054240e4-...-e0b5e84d3a35"
> IsPassive="false"
> IssueInstant="2012-02-28T06:43:35.704Z"
> ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
> Version="2.0">
> <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
> test_issuer
> </saml2:Issuer>
Therefore SAMLRequest I form as follows:
> private AuthnRequest buildAuthnRequestObject() {
> DateTime issueInstant = new DateTime();
>
> IssuerBuilder issuerBuilder = new IssuerBuilder();
> Issuer issuer = issuerBuilder.buildObject(
> "urn:oasis:names:tc:SAML:2.0:assertion",
> "Issuer", "samlp");
> issuer.setValue(issuerId);
>
> AuthnRequestBuilder authRequestBuilder = new AuthnRequestBuilder();
> AuthnRequest authRequest =
>
> authRequestBuilder.buildObject("urn:oasis:names:tc:SAML:2.0:protocol",
> "AuthnRequest", "samlp");
> authRequest.setForceAuthn(new Boolean(false));
> authRequest.setIsPassive(new Boolean(false));
> authRequest.setIssueInstant(issueInstant.plusHours(4));
> authRequest.setProtocolBinding(
> "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
> authRequest.setAssertionConsumerServiceURL(consumerUrl);
> authRequest.setDestination(idPDestinationUrlSSO);
> authRequest.setIssuer(issuer);
> authRequest.setID(authReqRandomId);
> authRequest.setVersion(SAMLVersion.VERSION_20);
>
> return authRequest;
> }
Then this message is compressed and encoded in Base64:
> private String encodeRequestMessage(RequestAbstractType requestMessage)
> throws MarshallingException, IOException {
> Marshaller marshaller =
> Configuration.getMarshallerFactory().getMarshaller(requestMessage);
> Element authDOM = marshaller.marshall(requestMessage);
>
> Deflater deflater = new Deflater(Deflater.DEFLATED, true);
> ByteArrayOutputStream byteArrayOutputStream = new
> ByteArrayOutputStream();
> DeflaterOutputStream deflaterOutputStream =
> new DeflaterOutputStream(byteArrayOutputStream,
> deflater);
>
> StringWriter rspWrt = new StringWriter();
> XMLHelper.writeNode(authDOM, rspWrt);
> deflaterOutputStream.write(rspWrt.toString().getBytes());
> deflaterOutputStream.close();
>
> String encodedRequestMessage =
> Base64.encodeBytes(byteArrayOutputStream.toByteArray(),
> Base64.DONT_BREAK_LINES);
> return URLEncoder.encode(encodedRequestMessage, "UTF-8").trim();
> }
Thus, this part - "SAMLRequest =" + SAMLRequest - is formed.
> "https://domain_name_of_idp_here/idp/profile/SAML2/Redirect/SSO?" +
> "SAMLRequest=" + encodedRequestMessage
As for SigAlg. I use:
> http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23dsa-sha1
Therefore, this part also is formed:
> "https://domain_name_of_idp_here/idp/profile/SAML2/Redirect/SSO?" +
> "SAMLRequest=" + encodedRequestMessage + "&SigAlg=" + SigAlg
Question in forming of this part:
> "&Signature=" + Signature
I get a signature so:
> public Signature getSignature() {
> KeyStore keyStore =
> KeyStore.getInstance(KeyStore.getDefaultType());
> FileInputStream fileInputStream =
> new FileInputStream(new File(jksFileName));
> keyStore.load(fileInputStream, jksPassword);
> fileInputStream.close();
> KeyStore.PrivateKeyEntry privateKeyEntry =
> (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias,
> new KeyStore.PasswordProtection(jksPassword));
> PrivateKey privateKey = privateKeyEntry.getPrivateKey();
> X509Certificate certificate =
> (X509Certificate) privateKeyEntry.getCertificate();
> BasicX509Credential credential = new BasicX509Credential();
> credential.setEntityCertificate(certificate);
> credential.setPrivateKey(privateKey);
>
> Signature signature =
> (Signature) org.opensaml.xml.Configuration.getBuilderFactory()
>
> .getBuilder(org.opensaml.xml.signature.Signature.DEFAULT_ELEMENT_NAME)
>
> .buildObject(org.opensaml.xml.signature.Signature.DEFAULT_ELEMENT_NAME);
> signature.setSigningCredential(credential);
> SecurityConfiguration securityConfiguration =
> Configuration.getGlobalSecurityConfiguration();
> String keyInfoGeneratorProfile = null;
> SecurityHelper.prepareSignatureParams(signature,
> credential, securityConfiguration, keyInfoGeneratorProfile);
>
> return signature;
> }
In the method buildAuthnRequestObject() is added:
> private AuthnRequest buildAuthnRequestObject() {
> ...
> authRequest.setSignature(getSignature()); // <---- to sign the request
>
> return authRequest;
> }
This message also compressed and encoded in Base64 and takes the form:
> <?xml version="1.0" encoding="UTF-8"?>
> <samlp:AuthnRequest AssertionConsumerServiceURL=
> "https://ip_of_my_sp_here/EsiaChecker_war/resp/"
> Destination=
> "https://domain_name_of_idp_here/idp/profile/SAML2/Redirect/SSO"
> ForceAuthn="false"
> ID="0"
> IsPassive="false"
> IssueInstant="2014-09-1T19:07:42.718Z"
> ProtocolBinding=
> "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"
> xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
>
> <samlp:Issuer xmlns:samlp=
> "urn:oasis:names:tc:SAML:2.0:assertion">
> my_issuer_here
>
> </samlp:Issuer>
>
> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
>
> <ds:SignedInfo>
>
> <ds:CanonicalizationMethod Algorithm=
> "http://www.w3.org/2001/10/xml-exc-c14n#"/>
>
> <ds:SignatureMethod Algorithm=
> "http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
>
> <ds:Reference URI="#0">
>
> <ds:Transforms>
>
> <ds:Transform Algorithm=
> "http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
>
> <ds:Transform Algorithm=
> "http://www.w3.org/2001/10/xml-exc-c14n#"/>
>
> </ds:Transforms>
>
> <ds:DigestMethod Algorithm=
> "http://www.w3.org/2000/09/xmldsig#sha1"/>
>
> <ds:DigestValue/>
>
> </ds:Reference>
>
> </ds:SignedInfo>
>
> <ds:SignatureValue/>
>
> <ds:KeyInfo>
>
> <ds:X509Data>
>
> <ds:X509Certificate>
> MIIEXD...0CFtd6whg==
>
> </ds:X509Certificate>
>
> </ds:X509Data>
>
> </ds:KeyInfo>
>
> </ds:Signature>
> </samlp:AuthnRequest>
But how to add a signature as a GET request parameter? To make it so:
*"&Signature =" + Signature*.
I would be very grateful for the information. Thanks to all.
-----
Kind regards, Alexey
--
View this message in context: http://shibboleth.1660669.n2.nabble.com/How-to-add-a-signature-as-a-GET-request-parameter-using-Java-and-OpenSaml-tp7606304.html
Sent from the Shibboleth - Users mailing list archive at Nabble.com.
More information about the users
mailing list