Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPS Server / Microsoft ADFS response? #7

Open
jdredd87 opened this issue Nov 18, 2024 · 5 comments
Open

HTTPS Server / Microsoft ADFS response? #7

jdredd87 opened this issue Nov 18, 2024 · 5 comments

Comments

@jdredd87
Copy link

Dealing with ADFS

It forcing to use HTTPS

Is there a way with the SPDemo.exe to have the server it creates, to be HTTPS with supplied cert files?

@jdredd87
Copy link
Author

I was able to modify the saml.http.server.pas to use HTTPS.

Now ti figure out how to parse the ADFS XML response. Doesn't match Auth0.com's so it blows up a little bit with missing fields like NameID ... and then if i remove that, it won't parse/show any attributes returned.

@jdredd87 jdredd87 changed the title HTTPS sp server? HTTPS Server / Microsoft ADFS response? Nov 19, 2024
@lminuti
Copy link
Collaborator

lminuti commented Nov 19, 2024

For your first question I usually put my SAML server behind a web server (apache, nginx, caddy, ...) with TLS and reverse proxy configured. For the problem with missing field if you send me the XML file (without sensitive information) I can try to figure out how to handle it.

@jdredd87
Copy link
Author

jdredd87 commented Nov 25, 2024

well I have the HTTPS part working... since it uses INDY and OpenSSL and such.
I have it so it works mostly, using HTTPS://LOCALHOST

I have gotten A little closer on things.... I can generate this XML SAML Request and fire it off...

`<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="BE3E313B52424C72BB8DACE18F39E690"
Version="2.0"
IssueInstant="2024-11-24T12:00:00Z"
Destination="https://server.com/adfs/ls/"
AssertionConsumerServiceURL="https://localhost/assertion">

<saml:Issuer>http://server.com/adfs/services/trust</saml:Issuer>

<samlp:NameIDPolicy
    Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
    AllowCreate="true" />

<samlp:RequestedAuthnContext Comparison="exact">
    <saml:AuthnContextClassRef>
        urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
    </saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>

</samlp:AuthnRequest>`

Using this as my SAML request, I finally get to a point, I can put in a user name and password.
But then fails afterwards about the SAML request not doing the whole back and forth signing section?

Not 100% sure yet what to do here. I assume use Sign PubKey and EncPubKey ? but what to exactly do/use, i haven't gotten that far yet...
Error details: MSIS7085: The server requires a signed SAML authentication request but no signature is present.

If I skip the SAML request, and go straight to a login page... and go through the process there, this is what the ADFS SAML response looks like...

<samlp:Response ID="_70940581-b4df-46b1-a3d7-0bada1f1288a" Version="2.0" IssueInstant="2024-11-25T04:47:10.534Z" Destination="https://LOCALHOST/assertion" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://server.com/adfs/services/trust </Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <Assertion ID="_14f49bf4-7640-4a23-8638-6fe9e048628a" IssueInstant="2024-11-25T04:47:10.534Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> <Issuer>http://server.com/adfs/services/trust</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/2001/04/xmldsig-more#rsa-sha256"/> <ds:Reference URI="#_14f49bf4-7640-4a23-8638-6fe9e048628a"> <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/2001/04/xmlenc#sha256"/> <ds:DigestValue>NBZEtf3yX8NLLedRxvHACDMIhjt5ZiNHkubdMLGvqms=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>azTfGqEcaRdZvjUS92PlWp1Z5zPmKgKbi0nxipvqq6/kFTeeQlBo6R9j9f8kZpkazuHEfoc6USsTVyNvrd/twEofQeg==</ds:SignatureValue> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Data> <ds:X509Certificate>MIIDdTCCAl2gAwIBAgIQQTdRlWQcV4dEN/KSKkeZhzANBgkqh+fFUUsxjevItqS4VkgYIaNh0OVtgOP+yWuyIZ6BsuH75CfzNl0PTmZaCIZfkK/Jkkg==</ds:X509Certificate> </ds:X509Data> </KeyInfo> </ds:Signature> <Subject> <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <SubjectConfirmationData NotOnOrAfter="2024-11-25T04:52:10.534Z" Recipient="https://LOCALHOST/assertion"/> </SubjectConfirmation> </Subject> <Conditions NotBefore="2024-11-25T04:47:10.534Z" NotOnOrAfter="2024-11-25T05:47:10.534Z"> <AudienceRestriction> <Audience>http://someserver.com</Audience> </AudienceRestriction> </Conditions> <AttributeStatement> <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"> <AttributeValue>[email protected]</AttributeValue> </Attribute> <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"> <AttributeValue>steven c</AttributeValue> </Attribute> <Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role"> <AttributeValue>CP Dev</AttributeValue> </Attribute> <Attribute Name="EmployeeNumber"> <AttributeValue>54</AttributeValue> </Attribute> </AttributeStatement> <AuthnStatement AuthnInstant="2024-11-25T04:47:09.220Z"> <AuthnContext> <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef> </AuthnContext> </AuthnStatement> </Assertion> </samlp:Response>

Hopefully this helps? ... So far this demo has taught me a number of things and I have been able to tweak it and change it to do what I need. But still got a bit more to figure out. The ADFS server setup, I have no control over, and have to bug people for details and help.

( edit, sorry, the XML i keep formatting and pasting here, keeps getting clobbered when looking at the post. But it looks fine in the editor here.... )

For now I can work around the parsing of the response. Already doing so.

But the request part, to handle the signing of the request, I am not sure what to do and what to put in the INI files.

@jdredd87
Copy link
Author

jdredd87 commented Nov 27, 2024

I pulled the two X509 certs from the meta data file.
I take it that this gives me the

"Sign PubKey" and "Enc PubKey" from the IDP tab...

On the "Service Provider" tab, there are 4 keys to set?

I was able to generate 2 pem files.

sp-private-key.pem ( this has the password set during generation ? )

sp-cert.pem ( this is what i take is the public file )

Then for "Sign PrivKey" this would be set to sp-private-key.pem

Then for "Sign PubKey" this would be set to sp-cert.pem

I don't know what the next two drop downs are for and what to set... "Enc PrivKey" and "EncPubKey" ( btw its labeled as encPutKey .... )

Also... do I need a password field or something somewhere to set a password for the sp-private-key?

In the function SignRequest, i had to modify this line

LSignatureContext.LoadKey(TBytesStream.Create(AKey.Data), AKey.Format, True);

into

LSignatureContext.LoadKey(TBytesStream.Create(AKey.Data), AKey.Format, 'mypasswordhere', True);

For it to get past that part. It would fail loading without a password.

But it gets to this line

LSignatureContext.Sign(LXMLDocument);

and crashes out it looks in the openssl libeay32.dll


:776ddd59 ntdll.RtlIsZeroMemory + 0x99
:776e6ff3 ; 
:776ed96b ; 
:776803f1 ; 
:7763f6f6 ntdll.RtlFreeHeap + 0x46
:110d268c ; C:\Software\Delphi-SAML\Demos\bin\libeay32.dll
:1100269d libeay32.CRYPTO_free + 0x1d
System.TInterfacedObject._Release
System._IntfClear(???)
:00c4f287 @IntfClear + $13
SAML.http.Server.GetAuthnRequest($4873850,$487A750)



which this is the exact code spot here that fails

procedure TSignatureContext.Sign(AXMLDocument: IXMLSecDocument);
var
  node: xmlNodePtr;
begin
  node := (AXMLDocument.FindNode(string(xmlSecNodeSignature), string(xmlSecDSigNs)) as TXMLSecNode).FNode;

  // sign the template
  if xmlSecDSigCtxSign(dsigCtx, node) < 0 then       <--------------------- FAILS HERE!
  begin
    raise EXMLError.Create('Error: signature failed');
  end;

end;

My thoughts on this possibly... if it has worked in the past... is maybe the OpenSSL DLL files... the ones from

https://www.zlatkovic.com/pub/libxml/

are from 2008! ... which won't work with Delphi / Indy SSL support.... which I need.... and am using the DLL's from
https://indy.fulgan.com/SSL/ which are mostly.. current-ish... but at least compatible with Delphi 11/12 Indy SSL support for the HTTPS server hosting.

:edit:

Using the OLD 2008 OpenSSL "works" on doing the sign part. Or so it seems.
It just breaks Delphi INDY SSL support for hosting the HTTPS server......

So now it generates a much bigger XML request for the SAML Request.

But ADFS fails it.

"MSIS0018: The SAML protocol message cannot be read because it contains data that is not valid."

So something with the

function TSAMLAuthnRequest.AsXML: string;

is not generating properly I think when it comes to ADFS.

Also 1.2.10 is the API / version this is wrapped/supporting... from 2013... ?

So all of this is quite a bit out dated.... and doesn't match up I guess with Latest versions of OpenSSL.

@jdredd87
Copy link
Author

jdredd87 commented Dec 1, 2024

Doing more messing around...
I did find i needed this in the INI file

SSOBinding=urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST

HTTP-POST by itself wasn't good enough.

I've been spending hours and hours a day on this... but only getting a bit further.. maybe?

I might have to throw in the towel and say to management that Delphi can't do SAML.

At least when it comes to ADFS.

I can't get anywhere on this.

I even setup my own 2022 Server and ADFS and got to same point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants