WSO2 IS 5.1.0, send session information as SAML claims - saml-2.0

We are considering to send some session information in the SAML claims.
The session information would be something to received by the chosen (custom) authenticator, such as value of an HTTP header (X509 DN), extra information provided on the logon screen, etc ...
Currently (by default) all claims are read from the userstore (as mapped by the claim mapping).
The only way I currently found to pass the session information is to implement/overwrite the SAML2SSOManager implementation.
Is there any simpler way to pass some user attributes from the authenticator which will be handled as a claim by the default SAML2SSOManager implementation?
I see the federated authenticators use context.getSubject().getUserProperties() to pass remote claims to the SAML response. Is it a way? ( regardless I put any ClaimMapping into the userProperties and declare the claim as required, I am unable to get it out as SAML response claim)
Thank you in advance

Apparently the way to go is implementing a custom ClaimHandler as described http://pushpalankajaya.blogspot.be/2014/07/adding-custom-claims-to-saml-response.html
The local authenticator can set the claims as user properties (of the subject).
In this case extending the handleLocalClaims should be enough, not to mess with federated mapping (where federated authenticators use the subject userAttributes as well)

Related

Azure AD B2C - SAML Integration Custom Policies - Disable InResponseTo check

I have custom policies setup within our Azure AD B2C tenant to setup a SAML based signin SP initiated flow. On receipt of the response from the third party IDP I get the exception "The response has an invalid relay cookie".
I believe this is because the IDP's response is missing the InResponseTo property. Having spoken to said IDP, they are not able to send back the InResponseTo property in their response.
Is there a way to either remove the InResponseTo property from our initial request, OR is it possible to disable checking the InResponseTo attribute on receipt of the response?
I've successfully run a signin using the same custom policies in B2C, but using https://samltest.id/start-sp-test/ as the IDP instead, and can see the InResponseTo property returned in the response from here. So this is the only thing I have been able to identify as the a possible cause.
I know this is bad practice / a security flaw, but we are trying to prove we can get the identity flow working with this third party, with a view this will be fixed at a later date.

What's the difference between User.Read and OpenID+Profile+Email scopes

Does User.Read "contain" the permissions email openid and profile? I've found that apps that are requesting the 3x scopes, can instead accept just the User.Read permission and still function equivalently
At work I'll get requests from the business to help them setup SSO using OIDC, and I'm not actually sure what permissions I should be giving them. Seems like either option works but I'd like to better understand what's happening
See my observations below:
I've created a basic Function App, and configured it to use OpenID Connect Image
My App Registration already has the User.Read permission with admin consent, so when I log into my Function, there's no issue.
Image
However, after removing the User.Read permission and logging in, I now get a permissions request prompt Image
And after consenting to the permissions, I can now see that email openid and profile permissions were added Image
Even more interesting, the permissions in the request prompt correlate to openid and offline_access, but offline_access wasn't added, while email and profile weren't in the request
I did find a similar question, but the accepted answer doesn't seem to align with what I see here
Generally I would favour the OAuth standard design where fields like these are Personally Identifiable Information (PII). So each app should only use the smallest scope it needs, as an information disclosure best practice. See also this Curity article.
Name
Email
Phone
Address
The Graph API can also be used with standard scopes, as in step 11 of this blog post of mine, where I wanted to get hold of user info in an API. So if this works for you I would prefer it. Personally I also prefer standard scopes so that my application code is portable.
Microsoft's design is based on each API requiring a different access token, the resource indicators spec. It is interesting, though perhaps not always intuitive. I am no expert on Azure AD though, and there may be some intended usage I do not understand.
User.Read is a scope intended to be used when requesting an access token for the Microsoft Graph API. It grants privileges to read the profile of the signed-in user only. A separate call to the Microsoft Graph API is required to retrieve the profile.
openid, email, profile and offline_access are OpenID Connect scopes:
openid is used to request an id token.
offline_access is used to request a refresh token which can later be used to get a new access token.
email to request an email claim.
profile to request several user claims (Eg.preferred_username).
Both email and profile can be used to augment information available in the UserInfo endpoint, however, it is recommended to use the id token which is already a superset of the information available at the aforementioned endpoint.

What scope does "idp" belong to in IdentityServer4?

My MVC client's access token contains an "idp" claim that my simple server-to-server client's token doesn't. I don't explicitly request idp on either clients, so where is this claim coming from? I thought it was part of "openid", and since it is available by default to MVC client, you don't need to request it, but I couldn't find any documentation/specification that confirms it. By the way, I am unable to add the openid scope to my serer-to-server client, as I am getting "invalid scope" error when I do that. What I am trying to do here is to get the "idp" claim into the token for my server-to-server client as well, but not sure if that's possible. Can someone point me to the right direction?
When you do server to server communication using the client-credentials flow, there is no user involved and hence the openid scope has no purpose. As its core purpose is to ask for the subject claim (the user Id).
The idp claim is not part of any scope and is usually added by IdentityServer.
Why do you neeed the idp claim? Your API and client both trusts the shared IdentiyServer.
idp claim in Identityserver stands for external identity provider (such as Google). That's why it does not have any sense when you request a token from your local IdP with "service_credentials" flow. If you are interested in the info about the token's issuer, just use iss claim instead. If you are sure you need the idp (or any other custom) claim in each and every token, you can involve a custom ClaimsService as I explained in my previous answer.

Trying to implement multiple ACS support with OneLogin

We are trying to implement SSO, using OneLogin as the IdP with our Cisco Call Manager cluster using a single agreement for all the servers in the cluster.
This just basically means that our metadata file contains a separate AssertionConsumerService tag for every server in the cluster.
However we are hitting an issue where in the SAML response the Destination is not recognized as valid.
My question would be, in the case of multiple ACS' used, what would the destination field need to look like in the SAML response? Does the IdP need to recognize which consumer the request came from and dynamically change the destination in the response to be the correct one for the specific consumer?
Right now the SAML response looks something like this:
<samlp:Response
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Destination="https://<CUCM_2>:8443/ssosp/saml/SSO/alias/<CUCM_2>https://<CUCM_2>:8443/ssosp/saml/SSO/alias/<CUCM_2>https://<IMP_1>:8443/ssosp/saml/SSO/alias/<IMP_1>https://<IMP_1>:8443/ssosp/saml/SSO/alias/<IMP_1>https://<CUCM_1>:8443/ssosp/saml/SSO/alias/<CUCM_1>https://<CUCM_1>:8443/ssosp/saml/SSO/alias/<CUCM_1>" ID="pfx117d2cec-f554-1fba-ff86-8db77b497e35" InResponseTo="s2ded98fb1a7423ea7bb1fcc95cf5c57ae3bf19684" IssueInstant="2019-02-18T16:06:06Z" Version="2.0">
and we get the same jumble for Recipient attribute in SubjectConfirmationData
With a proper cluster, you'd have a single ACS URL and the cluster would manage the user session between cluster members outside of SAML. I've not heard of multiple ACS URLs being used for a single SAML supporting SP. The IdP ( Onelogin ) needs to know specifically where to send the SAML response. I think you'll need to look at your cluster configuration and see whether it can be configured as a endpoint regardless of the cluster instance that initiates the SAML request.
Ah, but Cisco is special, don't you know? :)
I managed to get it working in the meantime and whoever is reading this thread in the future, I can confirm that OneLogin can now support Cisco clusters using a single cluster-wide metadata. But for any other IdP the setup is:
IdP requirements
CUCM only supports NameIDFormat as transient
HTTP-POST and HTTP-Redirect SAML bindings need to be enabled
SAML specification that allows for the definition of multiple AssertionConsumerService tags needs to be supported
Operation
When setting up SSO, within the metadata generated by CUCM if using cluster wide SSO mode, multiple AssertionConsumerService tags are defined. Two for each server in the cluster, one using the POST method and one using Redirect. Each ACS also has an Index tag, that starts at 0. This is sent to the IdP
When trying to authenticate a SAML request is sent to the IdP, within the request the AssertionConsumerServiceIndex field is set to the Index of the server from which the request was generated, as defined in the metadata originally provided to the IdP
The IdP then sends back a SAML response, in which the Destination and Recipient tags are set to match the Location tag from the metadata corresponding to the requesting server

Do we really need id_token in implicit flow in OIDC?

I'm working on a SPA application, and I'm using the recommended implicit flow and I'm able to get access_token and id_token. As I need more than the profile info, I've created a separate endpoint to return the user profile information (along with all the other information that's specific to our business) and this endpoint is protected, and can be accessed only with an access_token as the bearer token. Right after getting access_token in SPA, I call this endpoint to get all the user information (which includes first name, last name etc., that gets displayed on the UI). If there is any problem with the returned id_token and access_token pair, the user profile info endpoint call would fail. So, do I really need to validate the id_token? as I'm not relying on any information within that token.
For authenticating against external login provider or authorization code flow, validating the id_token makes sense, but in my case I'm not sure about it.
According to OpenID spec:
When using the Implicit Flow, the contents of the ID Token MUST be validated in the same manner as for the Authorization Code Flow, as defined in Section 3.1.3.7, with the exception of the differences specified in this section.
1. The Client MUST validate the signature of the ID Token according to JWS [JWS] using the algorithm specified in the alg Header Parameter of the JOSE Header.
2. The value of the nonce Claim MUST be checked to verify that it is the same value as the one that was sent in the Authentication Request. The Client SHOULD check the nonce value for replay attacks. The precise method for detecting replay attacks is Client specific.
Why don't you utilise response_type parameter in authorisation request. By changing its value, you can alter what you receive for authorisation response.
Identity documentation mention about possible response type values. Following is an extraction from their documentation,
As you can see, if you do not want SPA to receive the id token, you can set the response_type value to token. If you do so you will only get an access token, which is enforced by OAuth 2.0 specification. (See the OAuth 2.0's implicit flow response_type explanation from here). Note that when you use response_type=token , you are using OAuth 2.0 (not OIDC)
I don't see any wrong in your approach as long as you utilise features enabled by respective protocols.

Resources