OAuth 2.0 Client Credentials get user id - c#

I am using Identity Server 3 and following example from here. Client Credentials using OAuth 2.0.
I overwritten AuthorizeAttribute but when I look at the ClaimsIdentity Name and Actor are null. Is this by design? I am responsible to populate them? If so how? I see that Claims has client_id but why it's not getting reflected in Name or Actor?
Q: How can I get identity of who is calling?

We have two definition in OAuth, User and Client
User is a human participant which basically has username and password.
Client is an application which User use which has a client_Id and client_secret.
When you using Client Credentials there is no User involved, and only clientId and ClientSecret is sent, therefor both Actor and Name property is null, because these properties are bind to user. In this case you should use Password, Code or Implicit Grant Type which have user involved.

Related

How can i login to Salesforce that has Multi Factor Authentication on API calls?

I have started using MFA in Salesforce. I can successfully configure the setting "Multi-Factor Authentication for User Interface Logins" and use the Salesforce Authenticator app.
I have now enabled "Multi-Factor Authentication for API Logins", but in my C# app , the user enters Username, Password and Security Token and
I login to Salesforce via the following code:
SFService = new SalesForceEnterpriseService.SforceService() { Timeout = 80000, Url =
"https://login.salesforce.com/services/Soap/u/52.0"};
LoginResult result = SFService.login(Username, Password + Token);
But now i get the error:
INVALID_LOGIN: Invalid username, password, security token; or user locked out.
But i assume it is due to the MFA.
How can i now login a user if MFA is enabled in API logins and will i be able to make other API calls like getting Entity fields ?
No, it's not MFA. Go to FAQ, search for "API" and it clearly says MFA is not required.
Do you use normal Salesforce username and password or do you have Single Sign On enabled? API logins need SF credentials (or you can use an OAuth2 flow where human sees the SSO login page, types passwords there and then is taken back to your app. Entering SSO password directly to your app & logging in with SOAP won't work)
Go to your user's login history and view most recently used IP (and/or go to whatismyip.com). Go to Setup -> Network Access and add that IP to trusted ranges. This will mean you don't need security token anymore. Check if just username and password works better, maybe there were typos or it's an old token.

User Id in JWT token

I have a
back-end application - ASP.NET Web API
front end - React.
We are using a third party for authentication and have role based access for authorization.
We found an issue where in user who is authenticated and authorized was able to change an id say documentid in GET call (/API/Document/{documentid}) and was able to view other user data.
So after researching one way is to check on the call if the owner of the document (userid) matches the userid of the logged in. Since its Web API we cannot store the userid in session, so we had to set the userid in JWT. So when logged in we set the userid in JWT and we can make a check on the calls to see if the owner of the resource matches with userid in JWT. I see some concerns adding/exposing userid in JWT, so the question is what is the best way to handle it? I can make use of username but that might add an overhead of database call to get userid or add the username in every view model.

how to get the user attribute from aws cognito in c#

I am using AmazonCognitoIdentityProviderClient SDK.
I am trying to get a custom attribute for user in cognito. from c# front end i am passing username , password and email id. is there any function to retrieve the user atribute from cognito ?
After Cognito successfully authenticates a user in your pool, you will receive several JWTs - an access token, an ID token, and a refresh token. These tokens can be accessed in the authentication result object that is returned by the SDK (InitiateAuthResponse).
You can verify and decode the ID token to unpack the claims about the user's identity. This will also include any custom attributes you have defined on your User Pool. For .NET you can use JwtSecurityTokenHandler to decode the JWT (Sytem.IdentityModel.Tokens.Jwt namespace). After decoding the token, access the Claims property to get the user information. Custom attributes are prefixed with custom:, while Cognito attributes (such as username) are prefixed with cognito:.
Here's an AWS doc on how to decode the token: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html
Here's an example on how to use JwtSecurityTokenHandler: https://www.jerriepelser.com/blog/manually-validating-rs256-jwt-dotnet/
You can also use the Access Token to use the SDK to lookup a user directly, and the response from the AWS SDK will include the user attributes. Here's the doc on that: https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUser.html
Try Amazon.CognitoIdentityProvider.AmazonCognitoIdentityProviderClient.GetUserAsync(), it will return all standard and custom attributes. Please note that the method will only return the attributes for which a value is set.

Programmatically requesting access token on behalf of user

I want to programmatically get access token for the current user after logging in. I've figured out how to get a token using client credentials but I couldn't figure out how to get one on behalf of the user.
Here's what I tried to get using client credentials:
var client = new TokenClient("http://localhost:34240/connect/token", "client", "secret", AuthenticationStyle.PostValues);
var token = client.RequestClientCredentialsAsync(scope: "api").GetAwaiter().GetResult();
Do I need to use acr_values to add subject value to the request? If yes, how do I add it to the returned access token?
Or do I need to use code grant type instead? If yes, how do I request an authorization code programmatically?
Or is there another way that I'm missing?
I'd appreciate any help. I've checked IdentityServer samples but couldn't see anything about this.
Have a look at the Resource owner password grant examples. Basically you are doing almost the same, like you are currently doing, but instead of client credentials grant, you need to setup your client to use ResourceOwnerPassword, and then the code that you've shown, changes to:
var client = new TokenClient("http://localhost:34240/connect/token", "client", "secret", AuthenticationStyle.PostValues);
var token = client.RequestResourceOwnerPasswordAsync("<username>", "<password>", scope: "api").GetAwaiter().GetResult();
By this you are getting a token on behalf of the user. But have in mind:
The spec recommends using the resource owner password grant only for “trusted” (or legacy) applications. Generally speaking you are typically far better off using one of the interactive OpenID Connect flows when you want to authenticate a user and request access tokens.

Is user's consent towards a client relevant to the claims an api has access to?

In the documentation of IdentityServer4 it says:
[...] Consent is used to allow an end user to grant a client access to
resources (identity or API). This is typically only necessary for
third-party clients [...]
Does this mean an api can get access to claims the user did not consent to for the client the user logged into?
TL;DR
If I login to my mvc-client giving consent to permit Your email address, I get what I expect:
Secure-View of the mvc-client lists all claims from the identity token including the email address
Calling API using user token also shows email address as expected
But if I login and on consent screen tick off the permission for Your email address:
Secure-View of the mvc-client lists all claims from the identity token but not the email address (as expected)
But calling API using user token now also shows email address which I did not expect, or is this normal behavior?
Example-Configuration
I have this example (derived from the QuickStart Example 5):
mvc-client is from the sample
email-Scope is listed in Scope-definition of that client's OpenIdConnectOptions
AllowedScopes of that client include IdentityServerConstants.StandardScopes.Email
and the api api1 accessible by the mvc-client has IdentityServerConstants.StandardScopes.Email added to it inside UserClaims
I am using a custom profile service, but this should not be relevant to the question (just checked, the mentioned QuickStart example behaves the same way if configured like the steps described above)
I am answering this myself, but not yet accepting, since I am not 100% sure.
Yes, this is expected behavior, I think I just mixed up the different token types.
The api in my case is called using user token which effectively means access token.
From my understanding identity resources mentioned in the quoted documentation part does not apply to the access token (user identity is modeled by the identity token), so the behavior should be expected.

Categories