Showing posts with label SAML. Show all posts
Showing posts with label SAML. Show all posts

Tuesday, March 13, 2018

SAML : Decoding the SAML response

I've blogged before about this and I normally use the SAML Tracer running under Firefox.

Someone asked me about AWS Cognito and while I was having a look at this and doing some troubleshooting, I came across a page that also showed you how you can do this with PowerShell.

Basically, in your trace find the "SAML Response".

Then copy / paste it into:

[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("base64encodedtext"))

so something like:

PS C:\> [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64Strin
g("PHNhbWxwO2...c2FtbHA6UmVzcG9uc2U+"))

<samlp:Response ID="_f560b...9cf8c7d" Version="2.0" IssueIn
stant="2018-03-13T02:13:05.625Z" Destination="https://signin.aws.amazon.com/saml
" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" xmlns:samlp="urn:oas
is:names:tc:SAML:2.0:protocol">...</Assertion></samlp:Response>

Neat!

Enjoy!

Friday, January 29, 2016

ADFS : SAML IDP Initiated SLO

ADFS v3.0 - Server 2012 R2.

Been doing a PoC with client IDP Initiated via ADFS to a SAML ASP.NET client built on the ComponentSpace SAML stack.

Getting the login to work was somewhat trivial, getting the logout to work was somewhat harder!

The first ADFS error I got was:

MSIS0040: Received LogoutRequest element that is not NameID

Looking at the actual request, I noticed NameID was missing. This was because it wasn't one of the assertions in the login.

So I added a Transform in the RP claims rules to transform email to NameID.

Still got the error and I noticed that the outgoing NameID format was different i.e. email vs. unspecified

Fixed that in the claims rule.

I then got:


The verification of the SAML message signature failed.
Message issuer: https://roryb-lt001/MvcExampleServiceProvider
Exception details:
MSIS7074: SAML authentication request for the WebSSO profile must specify an issuer with no NameQualifier, SPNameQualifier or SPProvidedId properties. 


I have no idea what the bottom part of the error means but the problem was that ComponentSpace wasn't signing the logout.

So I added:

SingleLogoutServiceUrl="https://xxxl/adfs/ls/"
SignLogoutRequest="true"

to the saml.config.

(Note that you need a logout service URL as well).

So you need:

  • A NameID
  • The NameID format in the Logout must match that in the Login
  • The Logout must be signed

The signing could also be altered by using one of the ADFS PowerShell cmdlets.

The working logout looks like:

<samlp:LogoutRequest ID="_48141811-d3ab-4d1c-b073-9d8b240489ec"
                     Version="2.0"
                     IssueInstant="2016-01-28T21:30:26.736Z"
                     Destination="https://xxx/CompanyApp/Logout.aspx"
                     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://xxx/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/2000/09/xmldsig#rsa-sha1" />
            <ds:Reference URI="#_48141811-d3ab-4d1c-b073-9d8b240489ec">
                <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>9Zq1Y7AlKItUJdZYnIgpMxvzq48=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>pK+lQDO2/+zbXOSp8vzy...g82kSQ==</ds:SignatureValue>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <ds:X509Data>
                <ds:X509Certificate>MIIC8jC...2hdhC5uDwoc=</ds:X509Certificate>
            </ds:X509Data>
        </KeyInfo>
    </ds:Signature>
    <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
            xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
            >joeb@company.com</NameID>
    <samlp:SessionIndex>_d444eed6-1063-401a-8df1-11ea3f94b556</samlp:SessionIndex>
</samlp:LogoutRequest>

Enjoy!

Wednesday, January 27, 2016

AAD : Azure AD and IDPInitiated

Came across this very interesting post in SO.

Custom SSO With Azure Active Directory.

Note the IDPInitiated section:

"Finally, if your application expects IdP initiated SSO, construct a canned SAML AuthNRequest and save it in a URL - when your organization's users will click on this URL (canned SAML AuthNRequest) - they will get redirected to Azure AD where they will sign-in and then the token will be posted to the application's AssertionConsumerServiceURL - resulting in the user getting signed in. 

You can use the following tool to create a SAML AuthNRequest":

https://www.authnauthz.com/SAML/OutboundAuthNRequest

Azure AD doesn't have an IDP Initiated endpoint so this is a neat little trick!

Enjoy!

WIF : IDPInitiated and a WS-Fed application

I discussed IDPInitiated here:

ADFS : SAML redirect to application via relayState and loginToRp 

I've been looking at a case where IDPInitiated is used to a WS-Fed application.

The use case is:

IDP --> SAML --> ADFS --> WS-Fed --> Application

IDPInitiated is a SAML feature not supported in WS-Fed but it works in ADFS if you use the RPID construct.

If you set the RPID to the identifier of an RP in ADFS, the user will use IDPInitiated on their IDP to authenticate and this will go to ADFS, ADFS will see they are authenticated and pass the token onto the RP seamlessly.

However, you will get:

ID4216: The ClaimType '' must be of format 'namespace'/'name'.

The reason is discussed here:

AD FS 2.0: The Admin Event Log Shows Error 111 with System.ArgumentException: ID4216

Essentially, WS-Fed uses a SAML 1.1 token  and SAML 2.0 uses a SAML 2.0 token and SAML 1.1 is far stricter on the claim type.

It requires:

<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
    <AttributeValue> tom@abc.com </AttributeValue>
</Attribute>

Instead of:

<saml:Attribute Name="EmailAddress"
    NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
    <saml:AttributeValue      xsi:type="xs:string">tom@abc.com</saml:AttributeValue>
</saml:Attribute>

Note the difference in the attribute name formats.

Apart from this WIF breaks because all the classes expect the stricter URI form.

To sort this out:

On the IDP side, just pass everything through:

c:[]
 => issue(claim = c);


On the RP side, you needs to do a pass-through but using a custom rule e.g.

c:[Type == "EmailAddress"]
 => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", Value = c.Value);


That will keep WIF happy :-)

Enjoy!

Monday, January 11, 2016

ADFS : SAML redirect to application via relayState and loginToRp

This post follows on from:

IDP Initiated Sign-on to SAML SP using SAML IDP

Prior reading:


The question is around having a SAML IDP (Salesforce), ADFS as the RP-STS and multiple SAML RP.

Users may authenticate with either AD (via ADFS) or via Salesforce.

The easy way is to use RP Initiated but that wasn't an option.

In the link above, there is a useful tool to generate the relayState.

There are three text boxes:

IDP
RP-STS
Application

The article is somewhat confusing because the third text box refers both to a string to be passed to the application and the ADFS identifier of the application.

However, the use case we want i.e.

Identity provider security token server (STS) -> relying party STS (configured as a SAML-P endpoint) -> SAML relying party App

is supported.

I tried this with two ADFS - both v3.0.

So ADFS IDP = adfs-idp
ADFS RP-STS = adfs-rp-sts
Application ID = appid

which leads to:

https://adfs-idp/adfs/ls/idpinitiatedsignon.aspx
https://adfs-rp-sts/adfs/ls/
appid

and the URL is:

https://adfs-idp/adfs/ls/idpinitiatedsignon.aspx?RelayState=RPID%3Dhttps%253A%252F%252Fadfs-rp-sts%252Fadfs%252Fls%252F%26RelayState%3Dappid

So the user should authenticate on adfs-idp, be redirected to adfs-rp-sts, be already authenticated and then be redirected to the application.

However, I could not get this to work. I kept getting:

MSIS7001: The passive protocol context was not found or not valid. If the context was stored in cookies, the cookies that were presented by the client were not valid. Ensure that the client browser is configured to accept cookies from this website and retry this request.

If I left the third text box empty and removed the empty "RelayState=", I get:

https://adfs-idp/adfs/ls/idpinitiatedsignon.aspx?RelayState=RPID%3Dhttps%253A%252F%252Fadfs-rp-sts%252Fadfs%252Fls%252F

So the user should authenticate on adfs-idp, be redirected to adfs-rp-sts, be already authenticated and then select the application from the dropdown, This works.

For AD authentication, we can use the form at the top of the article i.e. using the loginToRp parameter.

This gives:

https://adfs-rp-sts/adfs/ls/idpinitiatedsignon.aspx?loginToRp=appid

So the user should authenticate on adfs-rp-sts and be redirected to the application, This works.

Or we can take a completely different approach (albeit with ADFS 3.0) as per:

ADFS 3.0: Playing with Authentication

where you can use:

Set-AdfsRelyingPartyTrust

where you can configure any of your relying parties to use specific claims provider(s).

Note:

Just to call out @RobM's summary from the forum question above:

"If you have a SAML IDP and a WS-Federation SP, you can use a URL constructed in the following manner to sign in:

https://corporate.adfs.com/adfs/ls/?wa=wsignin1.0&whr=https://identity.provider.com/&wtrealm=https://service.provider.com

If you have a SAML IDP and a SAML SP, the URL looks like so:

https://identity.provider.com/idploginpath/login?RelayState=RPID%3Dhttps%253A%252F%252Fidentity.provider.com

Note that with WS-federation, the flow is ADFS --> IDP --> ADFS --> RP

With SAML only, the flow is IDP --> ADFS --> RP"

Enjoy!

Thursday, January 07, 2016

ADFS : Support for SAML Scoping

With WS-Fed, the whr parameter allows you to specify the home realm and hence avoid the Home Realm Discovery screen.

What is the SAML equivalent?

There is relayState but relayState means two things:
  • IDPInitiated - similar to whr
  • SPIntitiated - used for context (similar to WS-Fed wtcx).
So for SPIntitiated, you're out of luck.

SAML also provides the Scoping parameter which performs a similar function.

An AuthnRequest using Scoping would look like e.g.

<samlp:AuthnRequest ID="_2528098e-4326-4fe2-83fd-72544c485420"
                    Version="2.0"
                    IssueInstant="2015-12-17T22:01:04.779Z"
                    Destination="https://xxx/adfs/ls"
                    ForceAuthn="false"
                    IsPassive="false"
                    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                    AssertionConsumerServiceURL="https://xxx/SAML/AssertionConsumerService.aspx?binding=urn%3aoasis%3anames%3atc%3aSAML%3a2.0%3abindings%3aHTTP-POST"
                    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    >
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://xxx/</saml:Issuer>
    <samlp:NameIDPolicy AllowCreate="true" />
    <samlp:Scoping ProxyCount="10">
        <samlp:IDPList>
            <samlp:IDPEntry ProviderID="https://blah.company.corp" />
        </samlp:IDPList>
    </samlp:Scoping>
</samlp:AuthnRequest>


Unfortunately, ADFS doesn't support this in v2.0 / v 2.1 / v3.0.

Hopefully, it will in v4.0.

Enjoy!

Tuesday, December 08, 2015

IdentityServer : ASP.NET MVC application to idsrv3 to ADFS via SAMLp 2.0

This continues the series of blogs I've done on IdentityServer 3.

This scenario involves idsrv3 as both an IDP to an ASP.NET MVC application and as a RP to ADFS. Also I'm using the InMemory option.

So the authentication chain is:

RP --> WS-Fed --> IS --> SAMLp 2.0 --> ADFS

Normally you would federate to ADFS via WS-Fed. However, in this scenario I want to use the
Kentor.AuthServices SAMLp stack so I'm using ADFS as a SAMLp IDP.

ADFS is v3.0. IS is version 3. This is being invoked by the Host.Web sample in idsrv3.

This builds on  IdentityServer : ASP.NET MVC application to idsrv3 to Kentor.AuthServices via SAMLp 2.0

Note by SAMLp 2.0 I mean the SAML protocol, not the SAML token.

The code in IdentityServerExtension.cs in the Host.Configuration project of idsrv3 would look like:

var authServicesOptions = new KentorAuthServicesAuthenticationOptions(false)
{
    SPOptions = new SPOptions
    {
        EntityId = new EntityId("http://localhost:44333/core")
    },

    SignInAsAuthenticationType = signInAsType,
    AuthenticationType = "saml2p",
    Caption = "SAML2p",
};

Uri metadataURI = new Uri("https://adfs.local/federationmetadata/2007-06/federationmetadata.xml");

authServicesOptions.IdentityProviders.Add(new IdentityProvider(
    new EntityId("http://adfs.local/adfs/services/trust"),
    authServicesOptions.SPOptions)
    {
        MetadataUrl = metadataURI,
        LoadMetadata = true,
    });

app.UseKentorAuthServicesAuthentication(authServicesOptions);

Now we need to configure ADFS. The idsrv3 metadata at core/wsfed/metadata refers only to WS-Fed not to SAMLp so we need to do this manually.

From the ADFS side, idsrv3 is a RP so we need to add a new RP.

Identifier tab:


We can leave out the certificates for the purposes of this exercise.

Endpoint tab:


where the second endpoint is:

https://localhost:44333/core/AuthServices/Acs

Under the Advanced tab, set the hash algorithm to SHA-1.

The claims rule mappings are exactly the same as per:

IdentityServer : ASP.NET MVC application to idsrv3 to ADFS

Then run up the MVC application. This should redirect to the idsrv3 Login screen. Click the SAML2p button, Authenticate on ADFS. You should be redirected back to the application, click the Contacts tab and you should see the claims displayed

If you want to see the actual SAML messages, use the excellent SAML tracer.

Enjoy!

IdentityServer : ASP.NET MVC application to idsrv3 to Kentor.AuthServices via SAMLp 2.0

This continues the series of blogs I've done on IdentityServer 3.

This scenario involves idsrv3 as both an IDP to an ASP.NET MVC application and as a RP to Kentor.AuthServices. Also I'm using the InMemory option.

So the authentication chain is:

RP --> WS-Fed --> IS --> SAMLp 2.0 --> Kentor.AuthServices

IS is version 3. This is being invoked by the Host.Web sample in idsrv3.

This builds on IdentityServer : ASP.NET MVC application to idsrv3 to ADFS. 

Note by SAMLp 2.0 I mean the SAML protocol, not the SAML token.

You need these NuGet packages:

Kentor.AuthServices

Kentor.AuthServices.Owin

Refer to the idsrv3 documentation.

The code in IdentityServerExtension.cs in the Host.Configuration project of idsrv3 would look something like:

var adfs = new WsFederationAuthenticationOptions
{
    AuthenticationType = "adfs",
    Caption = "ADFS",
    SignInAsAuthenticationType = signInAsType,

    MetadataAddress = "https://adfs.local/federationmetadata/2007-06/federationmetadata.xml",
    Wtrealm = "urn:idsrv3rp"
};
app.UseWsFederationAuthentication(adfs);

var authServicesOptions = new KentorAuthServicesAuthenticationOptions(false)
{
    SPOptions = new SPOptions
    {
        EntityId = new EntityId("http://sp.example.com")
    },

    SignInAsAuthenticationType = signInAsType,
    AuthenticationType = "saml2p",
    Caption = "SAML2p",
};

authServicesOptions.IdentityProviders.Add(new IdentityProvider(
    new EntityId("http://stubidp.kentor.se/Metadata"),
    authServicesOptions.SPOptions)
    {
        LoadMetadata = true,
    });

app.UseKentorAuthServicesAuthentication(authServicesOptions);

Note the ADFS section is just for context.

You need the following includes:

    using Kentor.AuthServices;
    using Kentor.AuthServices.Owin;
    using System.IdentityModel.Metadata;

You do not need to make any changes to the app / web.config.

The link in the code above viz. http://stubidp.kentor.se/Metadata points to a test SAMLp IDP which is a cool idea,

Then run up the MVC application. This should redirect to the idsrv3 Login screen. Click the SAML2p button, Authenticate on the test IDP (you can select different users from the dropdown). . You should be redirected back to the application, click the Contacts tab and you should see the claims displayed.

If you want to see the actual SAML messages, use the excellent SAML tracer.

Enjoy!

Thursday, November 19, 2015

ADFS : RelayState with IDPInitiated

I've been playing around with this lately so thought I would get all the references in one place.

Firstly. an overview : AD FS 2.0 RelayState.

Now I'm using ADFS ("AD FS") 3.0 so no need to install the hot-fix.

However, the feature is turned off by default so you need to turn it on as in Enabling RelayState In ADFS Versions.

And then you need the AD FS 2.0 RelayState Generator.

My use case is really simple:

SP --> ADFS (with a number of SAML SP).

I want to avoid selecting which SP. (And thus achieve the same objective as when I use the "whr" parameter with WS-Fed).

(Now as the first link alludes to, you could achieve this by using the loginToRp parameter instead).

So using the generator tool:













The actual URL is:

https://domain.local/adfs/ls/idpinitiatedsignon.aspx?RelayState=RPID%3Durn%253Acustomer%253Aserviceprovider1
%26RelayState%3Dhttps%253A%252F%252Fwebsite%252FServiceProvider%252FDefault.aspx

which for ease of reading is:

https://domain.local/adfs/ls/idpinitiatedsignon.aspx?RelayState=RPID=urn:customer:serviceprovider1&RelayState=https://website/ServiceProvider/Default.aspx

when URL Decoded.

Note: Don't be confused by the fact that RelayState serves two completely separate purposes. For IdPInitiated, the RelayState specifies the landing page at the SP. For SPInitiated it's a way for the SP to maintain state information between sending the AuthnRequest and receiving the SAML response. RelayState may be sent along with the AuthnRequest and the IDP must return this RelayState along with the SAML response.

Enjoy!

Wednesday, November 18, 2015

ADFS : SAML all the way through

I recently set up some ADFS 3.0 ("AD FS") servers as follows:

SP --> SAML --> ADFS A --> xxxx --> ADFS B --> Authenticate

The middle ADFS A is just passing everything through. SAML is the SAML 2.0 protocol.

What protocol is "xxx"?

I had thought that all ADFS to ADFS traffic was WS-Fed but to my surprise it turned out to be SAML. Which caused an error because I had configured the ADFS trust with SHA 256 rather than SHA 1.

So you see the AuthnRequest getting passed all the way up and the Response passed all the way down.

However, when I logged out, it didn't work.

Chatting to Mr. Google, I discovered that the SAML logout doesn't work if the token doesn't have a NameID claim.

So for ADFS B, you need a Transform rule to transform e..g. email to NameID.

And for ADFS A, you need a pass-through rule for NameID. Don't forget you need pass-through rules for all the claims from ADFS B on ADFS A.

Enjoy!

Thursday, November 05, 2015

SAML : Please do not roll your own

I've answered two questions on the forums today concerning SAML 2.0 protocol stacks that people are trying to roll on their own.

Not surprisingly, they are stuck and I can pretty much guarantee that there are security holes in their solutions that you could drive a Soviet May Day parade through!

SAML is hard, security is hard, writing security software is even harder,

Please use a library e.g. SAML : SAML connectivity / toolkit

Enjoy!

Monday, October 19, 2015

ADFS : Metadata signing

ADFS and pretty much all half-decent IDP's use metadata to transfer stuff like endpoints, bindings, certificates etc.

Sometimes you need to change some part of the metadata e.g. ADFS won't accept any endpoints that aren't https.

So to be able to import the metadata, you have to edit it.

However, if the metadata is signed, it will throw an error.

This is because the signature is a hash value of the contents so obviously if you change the contents you change the hash value.

What to do?

Note: Below is at your own risk as there may be security implications.

Metadata stands on its own. There are no other files involved, links to web collateral etc. So it stands to reason that if the metadata is signed, the fact that it is signed must be recorded somewhere within the metadata.

And in fact it is.

It use the "ds:Signature", "ds:SignedInfo", "ds:SignatureValue" etc. constructs.

So to remove the signature protection, simply delete the entire "ds:Signature" construct, Now you can change anything you want. And by extension so can anybody else!

To repeat: Use at your own risk as there may be security implications.

Enjoy!


Monday, October 12, 2015

ADFS : SAML 2.0 token

This question came up during a discussion with a customer.

They wanted Active Directory Federation Services (AD FS) to deliver a SAML 2.0 token.

Recall that ADFS delivers a SAML 1.1 token for WS-Fed and a SAML 2.0 token for SAML-P 2.0.

The easiest way is simply to configure the connection to use SAML-P 2.0 (P BTW for protocol).

Simply provide ADFS with metadata for a SAML-P connection.

If you can't do that, you can convert the token by using Azure ACS or by using thinktecture's identityserver as an intermediate step. Both allow you to configure the outbound token type.

While on the subject, did you know that ADFS on Server 2012 R2 (ADFS 3) can deliver JWT tokens for WS-Fed?

Refer : JSON Web Token (JWT) support in ADFS.

Enjoy!

AAD : Integrating with a custom SAML application as a SP

Most of the applications you want to integrate with Azure Active Directory (AAD) can be found in the Gallery. At the time of writing there's about 2,500 of them but the number just keeps increasing.

The big guns are there e.g. Salesforce and Workday and good to see Xero (from NZ) is there.

But what if your SAML application is not there?

Then you have to do it manually.

I've used the MvcExampleServiceProvider from ComponentSpace as the SP. This is a really good SAML library and it comes with heaps of examples that you can use OOTB.

In the Azure Portal - Active Directory - Applications - Add (at the bottom).

Select "Add an Application from the Gallery"


Select "Custom".

Give your application a name and then the click the Tick image.

Click "Configure single sign-on".

Select "Microsoft Azure AD Single Sign-On". Next


The Issuer is the URL of your application.

The "Reply URL" is:

http://xxx/MvcExampleServiceProvider/SAML/AssertionConsumerService

where "xxx" is the URL of my test box where the application is deployed (essentially localhost).


Note that my application is called "ComponentSpace".

Now copy these values into the saml.config.

"Issuer URL" goes on the first line and the sign-on / sign-off go into the last two lines.

My saml.config entry: 

&lt;!-- My Azure AD -->
  &lt;PartnerIdentityProvider Name="https://sts.windows.net/00...79/"
            SignLogoutRequest="true"
            WantSAMLResponseSigned="false"
            WantAssertionSigned="true"
            WantLogoutResponseSigned="true"
            UseEmbeddedCertificate="true"
            ClockSkew="00:03:00"
            SingleSignOnServiceUrl="https://login.windows.net/0...2/saml2"
            SingleLogoutServiceUrl="https://login.windows.net/0...2/saml2"/>  
 
Also remember the web.config change:

&lt;add key="PartnerIdP" value="https://sts.windows.net/00...79/"/
/>


Now run the application.

You should see:
Click the SSO link.

That should take you off the the Azure AD login page where you then authenticate and then the list of claims should be displayed.



If you use the SAML Tracer plugin to Firefox, you can see the actual SAML packets.

&lt;samlp:AuthnRequest ID="_95ff361a-61cb-4bf9-a5e7-529239ebdbb9"
  Version="2.0"
  IssueInstant="2015-10-11T19:08:38.045Z"
  Destination="https://login.windows.net/00...79/saml2"
  ForceAuthn="false"
  IsPassive="false"
  ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
  AssertionConsumerServiceURL="http://xxx/MvcExampleServiceProvider/SAML/
            AssertionConsumerService"
            xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
            >
  &lt;saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 
  >http://localhost/MvcExampleServiceProvider&lt;/saml:Issuer>
  &lt;samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:
            unspecified"
            AllowCreate="true"
            />
&lt;/samlp:AuthnRequest>

Note that the AssertionConsumerServiceURL is what goes into the ReplyURL in the "Configure App Settings" above and the Issuer is what goes into the "Issuer URL" box.

Enjoy!

Monday, August 17, 2015

Azure Access Panel : Federating with a SAML IDP (ADFS)

There is a new feature in Azure Active Directory where you can configure SAML 2.0 access to a 3rd party application that is not in the Gallery

Refer : “Bring your own app” with Azure AD Self-Service SAML configuration

I'm not going to repeat what's there but I thought that I would get this working to Active Directory Federation Services (ADFS). I have Server 2016 TP2 so I simply used that.

On the ADFS side, you need the Azure Active Directory (AAD) metadata. Not going into that - there's a zillion blogs on how to add a new Claims Provider.

In AAD, under "Applications" with the filter "Applications my company owns", select one and at the bottom you'll see "View Endpoints".



Click on that and you'll see:


Click on the "Copy" image on the right and import that metadata into ADFS.

Now I don't have an actual SAML 2.0 application i.e. an application with a SAML 2.0 client side stack. This is mainly because Microsoft don't have SAML client side support - you need to purchase a commercial one or use one of the open-source ones.

Refer : SAML : SAML connectivity / toolkit for some ideas.

So I'm just going to use the IDPInitiated page. That's enough to do a PoC to figure out how this stuff works.

Beware : ADFS : .IdPInitiatedSignonPageDisabledException 

The URL is:

https://xxx/adfs/ls/IdpInitiatedSignOn.aspx

So the configuration page inside of AAD is:


You would obviously have to put in the real "Reply URL" for an actual application etc.

The next page when you configure the "other" side i.e. ADFS you can ignore because you did that when you imported the metadata.

Give your users access rights as per the blog link above and then you will see your application in the Access Panel i.e.

myapps.microsoft.com

Click on the application icon, sign into AAD and you'll see:



If you use Firefox to run the Access Panel, add the "SAML Tracer" extension and when you click the icon, you'll see

in the trace.

The two SAML packets are the AuthnRequest and the Response ID.

Inside the Response ID, you'll see the attributes that you configured under the "Attributes" tab as per the blog link above.

Of course, it's much easier if the application you want is already in the Gallery and you just have to go through a simple wizard to achieve the same result :-)

Enjoy!

Monday, June 15, 2015

SAML : Federating with Azure Active Directory using SAML

This is SAML-P (the protocol) as opposed to SAML (the token).

There are a number of questions around about how you do this with AAD.

The official documentation SAML Protocol Reference is not very helpful but then I came across this:

Set up a trust between Shibboleth and Azure AD

The trick seems to be some "missing" documentation i.e. in:

Set-MsolDomainAuthentication   ,,, -PreferredAuthenticationProtocol SAMLP

Applying Mr. Google to "PreferredAuthenticationProtocol" bought me to:

Office 365 Supports SAML 2     and

Office 365 - Switching the federation protocol to SAML from WS-Federation

Note: Office 365 runs on top of AAD.

No idea why the documentation lacks this key element?

Enjoy!

Monday, May 04, 2015

SSO : Using Salesforce as an IDP

Had a number of questions around this lately and thought I would write this up.

The use case is that you have an existing Salesforce account and you want to use this to authenticate against an application.

Note that Salesforce federates using SAML.

Points to do this:
  • Hook up ADFS as the RP (SP in SAML speak) and Salesforce as the IDP using SAML
  • I don't believe you can do this with Azure AD. That's because AAD is always the IDP and everything else is the SP. That's how Salesforce out the SaaS back-end of AAD works i.e. access via the Access Panel / myapps.
  • Use Auth0 as in SAML : ASP.NET MVC application talking to SAML IDP . In this scenario, you are using the Auth0 Enterprise connection and configuring the SAML parameters similar to the ADFS example.
  • Use Auth0 but in this case use Salesforce as in the "Third Party App". Here Auth0 does some of the heavy lifting for you but the end result is the same.
Note: Auth0 does have a neat "Salesforce Configuration Instructions" tutorial available when you configure Salesforce as a "Third Party App" but it doesn't seem to be publicly available. The document doesn't tell you what to do on the client side. You need to add Salesforce to the Lock widget under "Connections / Social".

Enjoy!

Wednesday, April 15, 2015

SAML : ASP.NET MVC application talking to SAML IDP

By popular demand (yeah - all two of you!) I've expanded my previous post for a .MVC application.

SAML : .NET application talking to SAML IDP

Login to the Auth0 dashboard, create a new application.

Choose "Regular Web App." / ASP.NET.

You get a tutorial called "Using Auth0 with ASP.NET".

Make a project in VS - follow the tutorial.

I don't like IIS Express so I run in IIS but that's up to you.

If you logged in to the Auth0 dashboard, you see that the tutorial is pre-configured with the web.config settings. Neat!

Add the JS code for the widget somewhere - I just added it to the Contact page.

My callback URL is e.g.:

https://xxxWebApplication/LoginCallback.ashx

Remember to place this in the JS code (replace the dummy string there) and in the application entry in your dashboard under "Allowed Callback URLs".

Under Connections, remember to tick the ADFS-SAML entry as described in the previous blog entry referenced above.

OK - navigate to the website - Contact page - Login button. I only have the ADFS-SAML connection configured.



Make sure you have the SAML tracer tool enabled.

OK - click the login button - off to ADFS.

Authenticate.

(Note: If you get "Object reference not set to an instance of an object". it's probably because of proxy problems).

Now look at the SAML trace - you'll see a few orange SAML buttons - proving that you are talking to ADFS via SAML!



If you look at the LoginCallback,ashx.cs, you'll see code at the bottom to turn the JWT to a cookie ala the normal WIF SAML token flow. 

You can display this using the standard .NET WIF features (built into .NET 4.5) e.g.

How To: Build Claims-Aware ASP.NET MVC Web Application Using WIF

Remember to set the redirect at the bottom of the callback page.
context.Response.Redirect("Home/Contact");
 or whatever.

Enjoy!
 

 

 

Monday, April 13, 2015

SAML : .NET application talking to SAML IDP

I've blogged about this before viz:

SAML : SAML connectivity / toolkit

and the links inside that post.

The general problem is that you have a .NET application and you have a use case that requires you to authenticate with a SAML IDP.

There are two general approaches:
  • Add a SAML client side stack
  • Use something like ADFS as a bridge i.e. app --> WS Fed --> ADFS --> SAML --> IDP.
 Note that when I talk about SAML I refer to SAML-P (the protocol) as opposed to SAML (the token).

But then I came across Auth0.

This has an interesting approach. Instead of having many applications taking to many Identity repositories  (perhaps many-to-many - the spider's web scenario) , they have Identity aaS and each component has one connection into the circle. You then hook all the connections up with internal plumbing.

Internally, everything uses OpenID Connect. They also have something similar to the FIM metaverse concept i.e. a standard profile where they keep the essential information and that links all the different user identities together. So one profile holds that user's information for their Facebook, Twitter, ASP.NET Identity etc logins.

So how does this help the problem?

Auth0 provide a login widget (that they call Lock) that can be easily referenced by Javascript, code etc. This widget uses OpenID connect. The .NET applications uses this to get into the circle and then you configure another connection out of the circle which uses SAML to talk to the IDP. You then hook the two connections together.

Conceptually:

App --> OpenID Connect --> Auth0 --> SAML --> SAML IDP.

Now ADFS supports SAML-P so lets hook this all up as an exercise.

Following assumes you have an Auth0 developer account - which is free.

Auth0 has a number of samples on Github.

You can search for a MVC sample but for this particular investigation, I was interested in what Microsoft call a native device i.e. non-browser based. Mobile is a good example but so is command line or Windows Forms or WPF. There is a Forms / WPF example here.

In the example, where it says:

var auth0 = new Auth0Client(
   "{YOUR_AUTH0_DOMAIN}",
   "{YOUR_CLIENT_ID}");

You get these by creating a new App / API in the dashboard, Select:

Native Mobile App and then WPF / WinForms as the SDK Skip the Backend Platform.

You then get a tutorial. One neat thing is that if you log into the dashboard beforehand, all the tutorials are customised for your Auth0 domain and settings.The tutorial contains the settings you need, otherwise they are in the application settings for your application in the dashboard.

If you were looking for ASP.NET MVC, note that the only difference to the Forms / WPF approach is how you hook up to the widget i.e. you would use Javascript instead of C#. All the plumbing / configuration as below is identical.

Let's hook up the SAML.


Connections / Enterprise / SAML-P Identity Provider / Create New



You can give the connection any name you want and the URL's are the standard:

https://xxx/adfs/ls/

We'll ignore signing the request for now.

Now for the certificate:

ADFS wizard / Service / Certificates / right-click on Token-Signing / View certificate / Details tab / Copy to file

Choose Base 64 Encoded X509 (.CER)

Save this somewhere and then click "Upload Certificate" as above and upload it to Auth0.

Auth0 use a domain matching way to handle the typical Home Realm Discovery. In the "Email Domains" box above, enter a domain. This does not have to be a valid domain - just something that you can match on e.g. mysaml.co.nz. Yeah - I'm not wild about this either!

Now for the ADFS side - click on your new connection and then click the pencil (Setup). This shows the Auth0 endpoints or you can use the metadata link.

I just configured ADFS manually because I've done this so many times.

ADFS wizard / Trust Relationships / Relying Party Trusts / Add Relying Party Trust.

Going through the wizard:

Start / Enter data about the relying party manually / Next / Type any name you want / Next / AD FS profile / Next / ignore encryption so Next / Check enable support for SAML protocol- enter URL as below / Next / enter identifier as below / Add / Next / ignore MFA so Next / Permit all users / Next / Next / Close






Again, note that the strings above will reflect your Auth0 tenant and connection name.

Didn't bother with a signature because we are not signing the AuthnRequest. Note that these reflect the name I chose i.e. ADFS-SAML. You will use your name as reflected in the Auth0 endpoints.

Now edit the claims rules so they look like:




Now if you go back to your SAML connection in the Auth0 dashboard, you can click on the Try icon (the arrowhead) and if all goes well, it will come up with "It Works!". 



OK - so fire up the WPF application.



Enter e.g. joeb@mysaml.co.nz. This matched the Auth0 configuration so the Lock widget brings up the "Log in to mysaml.co.nz"

(BTW, if you are wondering about the social icons in the widget, this is configured in your application under Connections).

Click this and you will be redirected to ADFS where you can login as usual. Because you configured this to use SAML you now have a .NET application using SAML to authenticate. Neat!

Don't believe me? If you went with a standard MVC application and use FireFox, download the SAML tracer and run it (under Tools). Clear all your cookies, login in again and you'll see some of the entries in the trace have an orange SAML button.

Update: I wrote this up:

SAML : ASP.NET MVC application talking to SAML IDP

(BTW: I don't work for Auth0).

Enjoy!

Monday, July 21, 2014

SAML : I want to test my code

This question pops up frequently on the forums.

"I have written my own custom IDP / SP. How can I test it against some instance that's publicly available?"

There are a range of commercial products e.g. Tivoli, Oracle, Ping Identity. OpenAM which all deliver this functionality but they are complex to set up and are most certainly not free.

If you work in the Microsoft world and have a "spare" Windows server that's domain joined you can use ADFS. This runs on 2008 R2, 2012 and 2012 R2 and supports both IDP and SP mode.

Open source:

* Shibboleth 
*    and also Testshib
* simpleSAMLphp

Both these support IDP and SP mode.

Others:

SSOCircle - IDP only
Kentor - IDP only
Feide OpenIDP - IDP only
* Salesforce developer - (IDP / SP)

Beware: These are often simplified and some security checks have been removed so the fact that your code works in these environments does not ensure that they will work in the real world.

There are also some commercial / open source implementations for SAML stacks. These often have test IDP and SP that you can run up for basic testing.

ComponentSpace is one example.
onelogin SAML Toolkits - open source

There are others.

Enjoy!