The OpenID Provider issued an assertion for an Identifier whose discovery information did not match - asp.net

I used sample code from DotNetOpenAuth.net to become my own OpenID Provider (OpenIDProviderWebForm) everything worked fine and I was able to test my OP against NerdDinner. now I want to customize the identifier like --->
http://www.mydomain.com/user.aspx/Hash(Username+PrivateKey)~Username.
everything works on OP side but on the NerdDinner application when the app tries to do
HttpRequestInfo clientResponseInfo = new HttpRequestInfo("GET", auth, auth.PathAndQuery, headers, null);
response = RelyingParty.GetResponse(clientResponseInfo);
(you can find these two lines of codes in AuthController.cs from NerdDinner)
the response contains below error:
The OpenID Provider issued an assertion for an Identifier whose discovery information did not match.
Assertion endpoint info:
ClaimedIdentifier: http://localhost:57571/user.aspx/76208371132EC7F7A37472C8B4CC2CC37A05B707~sohail
ProviderLocalIdentifier: http://localhost:57571/user.aspx/76208371132EC7F7A37472C8B4CC2CC37A05B707~sohail
ProviderEndpoint: http://localhost:57571/server.aspx
OpenID version: 2.0
Service Type URIs:
Discovered endpoint info: [
{
ClaimedIdentifier: http://localhost:57571/user.aspx/EA467E35736AC22EB60C04C2E9D9594263B60ECB~sohail
ProviderLocalIdentifier: http://localhost:57571/user.aspx/EA467E35736AC22EB60C04C2E9D9594263B60ECB~sohail
ProviderEndpoint: http://localhost:57571/server.aspx
OpenID version: 2.0
Service Type URIs:
http://specs.openid.net/auth/2.0/signon
http://openid.net/extensions/sreg/1.1
}, {
ClaimedIdentifier: http://localhost:57571/user.aspx/EA467E35736AC22EB60C04C2E9D9594263B60ECB~sohail
ProviderLocalIdentifier: http://localhost:57571/user.aspx/EA467E35736AC22EB60C04C2E9D9594263B60ECB~sohail
ProviderEndpoint: http://localhost:57571/server.aspx
OpenID version: 1.0
Service Type URIs:
http://openid.net/signon/1.0
http://openid.net/extensions/sreg/1.1
},
]
anybody can help me please?

The relying party is reporting that the Provider is asserting information about an identifier that doesn't match what the OpenID discovery produces about that same identifier.
Your responsibility as a Provider includes making sure your assertion matches the identifier information. So consider what is under the "Discovered endpoint info" in the error message, and why it's different than what was asserted (above it). In this case, your ClaimedIdentifier and ProviderLocalIdentifier URLs are different between the asserted and discovered data. This may be because an HTTP GET on the asserted identifier actually generates an HTTP redirect to the URL under "discovered endpoint info", which you'd need to fix.

Related

Microsoft Graph API - sendMail API error - "The requested user 'foobar#private.com' is invalid."

I am trying to understand how to send mail using Microsoft Graph sendMail API after creating an Azure AD app with 'Application permissions' for Microsoft Graph 'Mail.Send' and 'User.Read'. I am successfully using the client_id, tenant_id and client_secret to obtain an apparently valid token and subsequently submitting a POST to the api like this (R code):
from_address <- "foobar#private.com"
url <- paste0("https://graph.microsoft.com/v1.0/users/", from_address, "/sendMail")
resp <- POST(url,
add_headers(.headers = c(content_type = "application/json",
Authorization = paste("Bearer", token))),
body = upload_file("mail.json"))
The content of "mail.json" is:
{
"message": {
"subject": "Meet for lunch?",
"body": {
"contentType": "Text",
"content": "The new cafeteria is open."
},
"toRecipients": [
{
"emailAddress": {
"address": "someone#somewhere.com"
}
}
]
}
}
However, I get this 404 response:
"{\"error\":{\"code\":\"ErrorInvalidUser\",\"message\":\"The requested user 'foobar#private.com' is invalid.\"}}"
The Microsoft account I am using is private and the address represented above with foobar#private.com is the main 'signin' mail address for the account. I'm not sure if this user needs some special permissions or if it has to be a "corporate account". The plan is to use this within a corporate Microsoft account to send mails but I am currently testing with a private account to determine how it works.
The syntax for the call is
POST /users/{id | userPrincipalName}/sendMail
The tricky part is, as far as I can tell, personal Microsoft accounts don't have a userPrincipalName. Your "foobar#private.com" is an email address, but it isn't used as an identifier within Azure Active Directory or Graph.
Instead, you have to use your ID. You can get this with
GET /me
and the ID is the id field in the response.
Note that you may run into a separate problem with using an email address in the call, when it comes to work & school accounts. Commonly, people will have an address like "firstname.lastname#company.com", but this is only an alias for convenience; their userPrincipalName might be something more cryptic like "id123456#companytenantname.com". For this reason, it's best to stick to IDs throughout.
The description of how to POST to the Microsoft Graph SendMail api are correct in the question. The problem was only in the configuration of the application in Microsoft Azure portal Active directory. The administrator of the tenant created an app with two permissions with 'Admin consent'. The first is a Delegated permission, Microsoft Graph: 'Sign in and read user profile' the second is an Application permission, Microsoft Graph: 'Send mail as any user'. The first is used to get a token that is valid for 1 hour and the second is used in the code you see in the question to send the mail itself with the aquired token. I have been told that there is a restriction in place that only makes it possible to send mail from one specific 'no-reply' address at the organization so you can't use the api to impersonate someone else. It is not clear to me how that restriction works just that is does.

How to verify a HS256 signed JWT Token created with Keycloak authentication provider on jwt.io

I am trying to verify a HS256 JWT Token generated with locally ran KeyCloak Authentication Provider on https://jwt.io.
The KeyCloack instance is running on my local machine inside a docker container. I have applied almost the same steps as described in this answer (which on contrary applies the RS algorithm instead, and works as described): https://stackoverflow.com/a/55002225/1534753
My validation procedure is very simple:
1.) Request the token (with Postman) from my local docker KeyCloak instance with:
POST requesting http://localhost:8080/auth/realms/dev/protocol/openid-connect/token
2.) Copy the token contents inside the jwt.io's "Encoded" section
3.) I verify that the header and payload are as expected and correct
4.) I copy the client secret from my KeyCloak instance admin dashboard, you can see the reference on the image below:
5.) I paste the secret into the "VERIFY SIGNATURE" section on jwt.io and the "Encoded" token section changes, hence resulting with an invalid signature and a invalid (i.e. different) token.
My core question is what am I missing here? Why does the token change when I apply the expected secret!? Am I applying the right secret, the one from the client? If I understand JWT infrastructre and standard correctly then It should stay the same if the secret (with the expected algorithm applied) is valid. My reasoning is that something with JWT creation on KeyCloak is specific. I have not touched the HS256 algorithm provider on KeyCloak, everything is used as default with the docker installation guide on using KeyCloak. The settings related to the token and algorithm are setup to use HS256, and the algorithm is specified as expected in the JWT's header section correctly which can be verified after the encoded token is pasted into the jwt.io's page.
I need this to work as I am trying to apply the same JWT validation process inside a .NET Core web API application. I have encountered this whole issue in there, i.e. inside the System.IdentityModel.Tokens.JWT and the JwtSecurityTokenHandle.ValidateSignature method which results with an invalid signature and finally resulting in an exception.
On side note, I am accessing the token with Postman and its Authorize feature the configuration can be seen on the image below:
One more side note is I have a user "John" which belongs to my "Demo" realm. I use him to request an access token from KeyCloak.
To get the secret used for signing/verifying HS256 tokens, try using the following SQL:
SELECT value FROM component_config CC INNER JOIN component C ON(CC.component_id = C.id) WHERE C.realm_id = '<realm-id-here>' and provider_id = 'hmac-generated' AND CC.name = 'secret';
If you use the resulting secret to verify the tokens, the signature should match. I’m not sure if this secret is available through the UI, probably not.
Source: https://keycloak.discourse.group/t/invalid-signature-with-hs256-token/3228/3
you can try using Keycloak Gatekeeper.
If you want to verify that token in that way you need to change the Client Authenticator to "Signed JWT with client secret", otherwise you can use this "Gatekeeper" option. Here you can read more about it.

What is the correct way to configure Identity Server 3 for authorization code flow with SPAs?

We have an instance of Identity Server 3 which has been used for some time with various clients, some using implicit flow, others using client credentials. We now have a new requirement to integrate an iOS native app with this identity provider. I understand these days implicit flow is not recommended and public facing apps should instead be using authorization code flow. Examples of such advice are here and here.
By my understanding, authorization code flow has a step whereby a received authorization code is exchanged for JWT tokens via some back channel by supplying it alongside a client ID and secret. However, with SPAs and native apps we don't have the luxury of storing secrets. The guidance I found here would suggest I can simply omit the secret from the connect/token request, but my testing so far doesn't confirm this. So I'm stuck. To demonstrate, I've set up a client on my local instance of IS3 to test with:
{
'clientId': 'test',
'flow': 'AuthorizationCode',
'name': 'test',
'redirectUris': [ 'http://localhost:8080/' ],
'scopes': ['openid','profile']
}
I then make the following GET request to my IdP:
[ID_PROVIDER]/connect/authorize?client_id=test&redirect_uri=http%3A%2F%2Flocalhost%3A8080&scope=openid%20profile&response_type=code
This lets me sign in and returns me to my test app running at http://localhost:8080 with my authorization code in the querystring.
I now try to exchange this code for JWT tokens by POSTing to [ID_PROVIDER]/connect/token with the following body: code=[AUTH_CODE]&grant_type=authorization_code&client_id=test&redirect_uri=http%3A%2F%2Flocalhost%3A8080
But Identity Server rejects this with an HTTP 400 and invalid_client error. When I dig into its logs I see a ClientSecretValidator event with message "No client secret found". Which kind of makes sense based on my understanding outlined above, but given people are recommending using this flow for public-facing apps I must be misunderstanding something.
If anyone could clarify that'd be great, thanks.
You can't just omit the client secret. For your native case, I'd consider embedding the secret within the app. The authorize request will still have to validate the return_uri (custom URI scheme for your native app) and if that still feels insecure, you can also lean on Proof of possession (PoP) tokens (https://identityserver.github.io/Documentation/docsv2/pop/overview.html).
For a SPA app I would keep it implicit flow, I see no point in doing secrets there.

Error "WIF10201: No valid key mapping found" when trying to create claims from SAML

I am trying to validate a SAML response which is coming from Siteminder IDP from a third party. I have installed the certificate provided by them. When I call the ValidateToken method (System.IdentityModel.Tokens) to create claims, I get following error :
WIF10201: No valid key mapping found for
securityToken:'System.IdentityModel.Tokens.X509SecurityToken' and
issuer: 'issuer uri'
I dug in deep to find the error and its being thrown by method GetIssuerName (System.IdentityModel.Tokens).
Where is the problem? I googled for this issue but didn't find anything specific to my case. Does the SAML token from my client have a problem or there is something I am missing in implementation. I am fairly new to federated auth so please excuse any inaccuracy with the terminology used.
Gaurav
Ok found the solution but could't quite understand the readon behind it (complete noob, will update the answer when I know more).
Followed this approach of converting the SAML2 response to WSFed response, then on that new token I ran my code, now the error is gone.
http://blogs.msdn.com/b/bradleycotier/archive/2012/10/28/saml-2-0-tokens-and-wif-bridging-the-divide.aspx
Note : you still have to override the validate token method (which I had originally done) to avoid the following error :
“ID4154: A Saml2SecurityToken cannot be created from the Saml2Assertion because it contains a SubjectConfirmationData which specifies an InResponseTo value. Enforcement of this value is not supported by default. To customize SubjectConfirmationData processing, extend Saml2SecurityTokenHandler and override ValidateConfirmationData.”
Thanks.
You are probably missing a configuration that maps the issuer name (as specified inside the token) to the certificate (probably specified with a thumbprint). I guess you solve this with some configuration in your web.config. Have a look at p.e. Microsoft validating issuer name registry The page contains some sample configuration. Setting this up correctly depends entirely on your situation.
I wanted to make a note for future reference, since I also ran into this error but my resolution was different. I got the WIF10201 error in a custom MVC application that is using ADFS (3.0) claims-based authentication under Windows Server 2012. In the web.config of the MVC application, the thumbprint of the ADFS token signing key is recorded. It turns out, when the signing certificate is about to expire, ADFS creates a new key. The new key is marked "primary" and the old key is marked as "secondary" in the ADFS console (under AD FS/Service/Certificates). So in my web.config there was, of course, still the thumbprint of the old (secondary) key. As soon as I replaced it with the thumbprint of the new (primary) key, the error disappeared.

Connect to data/service wsdl URL introspect error

Hi I am trying to add a web service in flex 4. This web service is deployed in share point 2010 in the intranet . I am able to see this wsdl file through browser but trying to introspect the service is giving an authentication error.
I am getting the following error :-
There was an error during service introspection.
WSDLException: faultCode=OTHER_ERROR: Unable to resolve imported document at 'http://sql2008:47672/_vti_bin/StoryboardingDatabaseConnect.asmx?WSDL'.: java.io.IOException: Authentication failure
Edit :-
Have added the video showing the error at http://www.youtube.com/watch?v=moXfxmiHAqQ
The Data Services Wizard does not support (as of now, afaik) connection to https services, neither to ones that need authentication.
So you should add your credentials manually to your soap request's header using name-value pairs:
[{name: "userName", value: "yourUserName"},
{name: "password", value: "yourPassword"}].
You can read more about it in the Working with SOAP Headers section of this article (Using WebService components).
You might also find this post from the Adobe forums useful, elaborating this issue.

Resources