Why SAML request does not contain any credentials? - azure-active-directory

I am reading documentation about microsoft azure active directory. Here request sample:
<samlp:AuthnRequest
xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
ID="id6c1c178c166d486687be4aaf5e482730"
Version="2.0" IssueInstant="2013-03-18T03:28:54.1839884Z"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://www.contoso.com</Issuer>
</samlp:AuthnRequest>
As you can see this does not contains any login or pass. Why? How azure figure out actual credentials?

Authentication request in SAML is a trigger that initiates a sequence that leads to authentication of a principal and subsequent assertion with claims about this principal.
From SAML 2.0 spec:
When a principal (or an agent acting on the principal's behalf) wishes
to obtain assertions containing authentication statements to establish
a security context at one or more relying parties, it can use the
authentication request protocol to send an message
element to a SAML authority and request that it return a
message containing one or more such assertions.

Related

How to obtain the attributes of a saml response sent by Azure Active Directory?

I have a saml response that gives me azure active directory when doing the process with saml 2.0, the whole process is done normally, I send a saml request and the azure active directory returns the saml response, to do the whole process I have based on this guide, I've been reading a bit and I've noticed that Azure AD in the saml response sends the values within this tag:
<xenc:CipherData>
<xenc:CipherValue>VALUE HERE</xenc:CipherValue
</xenc:CipherData>
And not inside:
<AttributeStatement><Attribute Name="IDPEmail"><AttributeValue>administrator#contoso.com</AttributeValue></Attribute></AttributeStatement>
as specified in the documentation. The question is, how to get the true values that azure active directory is sent to me and not these encoded values, I am using Python 3 and Google App Engine, in addition to mentioning azure active directory and saml 2.0 to do the login process, I leave the SAML response complete in this url in case it serves to give a better context to my question.
As mentioned above, the SAML response you are getting is encrypted. Specifically Azure is encrypting its assertions (including the ones you are looking for) inside an encrypted body called CipherData.
You have two options:
1 - Disable SAML response encryption.
Azure AD calls SAML response encryption as SAML token encryption which is a bit confusing. You can follow this guide to disable the response. You must have uploaded an encryption public key/cert before.
2 - Configure your service provider to supported encrypted SAML responses.
The SAML token is encrypted.
You need to get the client side certificate used for this and use that to decrypt it.

How do I authorize an user to my rest service - Camel CXF

I have a httpd front end server which will authenticate users using openidc and associate JWT to the incoming request if the authentication is successful. Post this the request will reach the desired REST service, which is defined using Apache Camel CXF.
Now I need to deny/permit this user to the requested service based on certain permissions. How do i do that ?
Typically the established user session would contain claims about the user provided by the OpenID Connect Provider. Those claims can be used in mod_auth_openidc specific Require directives e.g.:
Require claim email:joe#example.org
For more information see: https://github.com/zmartzone/mod_auth_openidc/wiki/Authorization

What happens during a AcquireTokenAsync call using the client certificate?

In Azure AD, when we make a call such as AuthenticationContext.AcquireTokenAsync(resource, new ClientAssertionCertificate(_clientId, _cert)) it is not clear what exactly happens.
What part of the certificate gets exchanged if any?
Is there a challenge/response taking place?
Is the private key needed on the client as a part of this?
There are two ways you could go about finding the answer to you questions. One would be to look at the Microsoft Active Directory Authentication Library (ADAL) for .NET source code on GitHub, since this is open-source. The other (which we'll do here) is to looking at the network request that AcquireTokenAsync(String, ClientAssertion) generates, and work backwards from there.
Using Fiddler (or any other traffic analyzer), we can see something like the following (formatted for readability):
POST https://login.microsoftonline.com/{tenant-id}/oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&resource=https%3A%2F%2Fgraph.windows.net
&client_id={app-id}
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ
Breaking it down:
grant_type=client_credentials tells us this is a token request using the OAuth 2.0 Client Credentials Grant flow.
resource=https%3A%2F%2Fgraph.windows.net gives the URI of the resource the client is requesting an access token for. In this case, it's for the Azure AD Graph API.
client_id={app-id} is the client identifier. In Azure AD, this is the app ID of the application that was registered.
The presence of client_assertion_type and client_assertion are indicative that the client is using an assertion to authenticate:
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer says that client assertion being used is a signed JSON Web Token (JWT).
client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ is the aforementioned signed JWT token. The authorization server (e.g. Azure AD) will validate the contents, and check that the token was indeed signed by the certificate authorized for the client in question.
So, what ADAL does is:
Construct a token with a set of claims about the client (your app)
Use your certificate's private key to generate a cryptographic signature of those claims
Bundle that up into a signed JWT
Make an appropriately formed token request to the authority
During AcquireTokenAsync, only the certificate's thumbprint is provided (it's included in the JWT header to help the authorization server look up the corresponding public key). The JWT's signature is what proves that the client is in possession of the private key. However, before AcquireTokenAsync(String, ClientAssertion) can be used successfully, the client owner (i.e. you) needs to have provided Azure AD with the certificate's public key.
There is no challenge/response taking place here. The token is obtained in a single request, initiated by the client.
For a lot more detail, you can review the standards that this all implements:
RFC 6749: The OAuth 2.0 Authorization Framework
RFC 7521: Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
RFC 7519: JSON Web Token (JWT)
(Note that ADAL has a cache. Everything I described above will take place only if ADAL does not find a valid access token in the token cache. You can use AuthenticationContext.TokenCache.Clear() to clear the cache for experimentation.)

Reusing SAML assertion

I am implementing single sign on with multiple SPs. Here is my basic understanding:
1) Browser(User) requests resource from Service Provider (SP).
2) SP Redirects (with SAML Request) to Identity Provider (IdP).
3) Since it is first login, User gives the (IdP) his/her valid credentials.
4) IdP then redirects Browser (with SAML Response which includes SAML token) to the SP page.
Now let's say I have Service Provider A and Service Provider B. A user has completed the step about for Service Provider A. From service provider A (salesforce.com in my scenario), I have written a server-side method which instantiates a callout to an endpoint on Service Provider B. Is it possible to re-use the SAML assertion in this case? I.e. will service provider B trust the backend method?
You would have to customize Service Provider B in order for it to accept, understand and interpret the Assertion obtained by Service Provider A. It would certainly not work out-of-the-box.
The SAML Assertion included in the SAML Response to Service Provider A contains pieces of data which correlate it with the original SAML Request and define recipients of the message (for example using elements SubjectConfirmationData and Audience). The Service Provider B would need to ignore values in these fields, as it is actually not the indented recipient of the Assertion.
The problem of how to broker trust between two machines where user's identity is asserted by an identity provider can be solved with multiple standard approaches. One is to use a Session Token Service (based on WS-Trust) which defines how to request and issue tokens to 3rd party services. Another is to use OAuth 2.0. You could of course also simply authenticate Service Provider A to Service Provider B using a custom scheme with a password, HMAC, ...
The short answer - no if Service Provider B is implemented as a standard SAML 2.0 SP.
SAML 2.0 assertions are "targeted" and signed. They have a specified audience and a recipient URL. You cannot change them without breaking the signature.
The assertion received by SP A contains the name of SP A as audience and the ACS end point of SP A as recipient URL. Such an assertion will not be accepted by SP B.
What prevents you from just calling SP B in a standard way and let it initiate its own SAML 2.0 flow? Another option would be to perform an IDP-initiated SSO flow for SP B. Not all IDP implementations support it though.

Setting up OpenSSO (OpenAM) for Identity Provider scenario

We have an OpenSSO (OpenAM) instance set up at our end to work as a Service Provider (SP). It's been working well so far in an SP Initiated SSO scenario, however, I recently had to set it up for an IDP initiated scenario and am unable to get it to work successfully. To explain, in this scenario, the IDP would like to send the SAMLResponse directly to the Assertion consumer service at my end and our OpenAM instance should be able successfully digest the response and send the user to our underlying application. My questions are:
Is there any other configuration required in this scenario except for exchanging/uploading the metadata between the IDP and us (SP)?
Can I upload the metadata of the iDP in the same COT as the other IDPs that are currently working in the SP Initiate Scenario? Or should there be a new COT for each IDP provider?
What URL should I provide to the IDP to send the SAMLResponse to? Is it the AssertionConsumerService index="1" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" from our metadata? I tried this a few days back and OpenAM reported an error - "this is not the right consumer service for this request" or something.
I got an answer for this on an OpenAM forum -
http://lists.forgerock.org/pipermail/openam/2012-August/007872.html

Resources