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.
Related
I'm developing an .NET Web API and using JWT tokens to secure it. In my research of the best way to implement it, i decided to use the jwt claims to also limit the access to content, depending on specific claims present on the token. I can now manually verify if for example, a userId matches with the userId of a record's userId and return it if it's a match, but this is very tedious and not quickly adds up the amount of code just to do the same task...
Is there a way to implement something like an action filter to apply the claims to every request and return only the records that match the information in the token?
Thanks everyone in advance
See this implementation on this project.
https://github.com/cuongle/WebApi.Jwt/blob/master/WebApi.Jwt/Filters/JwtAuthenticationAttribute.cs
It's a simple scenario.
JWT contains a user's id or some claims.
You have a WEB API endpoint like ("GetCurrentUserData()") decorated with your custom ActionFilterAttribute.
Within that method you will call a helper function that will read the current request user claims and return them in a simple form (like user id).
See: Get claims from a WebAPI Controller - JWT Token,
Then within the method you can query/filter your returned data based on the Id/Claims of the current user of the request.
I have a web app which uses the Xero.NetStandard.OAuth2Client package to allow for authentication with Xero.
Once the user is redirected back into my app, I use the IXeroClient.RequestAccessTokenAsync method to exchange their code for an IXeroToken object, which allows me to make calls against the Xero API, as expected.
The one thing I do not know how to do, and which I can't seem to find in the official documentation, is how do I extract the user's details (namely their name and email address) from the IXeroToken object.
As per the standard, the information is encoded as JWT string in the IdToken property, but I am not sure how I am meant to get the information out of it without an additional dependency.
The built in System.IdentityModel.Tokens.Jwt.JwtSecurityToken class can deserialize the IdToken payload.
new JwtSecurityToken(accessToken.IdToken).Claims contains all the claims in the token.
The relevant types are:
email - The user's email
xero_userid - The user's id (guid)
given_name - The user's first name
family_name - The user's last name
The claims' existence is obviously conditional to the appropriate scope being set.
I want remove the users from Azure subscriptions programmatically.
We have lot of ways in the web to remove the AAD user but I could not find source to remove the users from Azure subscriptions.
Can we remove the user from Azure subscriptions programmatically?
How can we do this?
Have you tried working with the Azure API Reference? Specifically authorization?
You may be interested in the Role Assignments API.
Here's a support article regarding those assignments and how to utilize the API: https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-rest
Finally i found the answer. We have to do multiple steps to remove the user from Subscription.
Before we start implementing the below steps you need to create Client Id and client secret and create auth token using those client id and secret.
First i am fetching all the users by below GET API. Here is URL for reference.
example get method URL for above reference is: https://management.azure.com/subscriptions/{your subscription id here}/providers/Microsoft.Authorization/roleAssignments?api-version=2015-07-01
Above URL will fetch all the Users principal Id(User GUID) and RoleAssigementID.
Then you can delete a specific user you want. Same above URL has reference to remove the User from Susbcription.
example delete method URL for above reference is: https://management.azure.com//subscriptions/{your subscription id here}/providers/Microsoft.Authorization/roleAssignments/{User role Assignment id}/providers/Microsoft.Authorization/roleAssignments/{User role Assignment id}?api-version=2015-07-01
You can find the role assignment id from the first step.
Extra information:
First step will fetch principal id and role id but if you need other information of the user(ex: emailid, name, etc) you can use Graph API to fetch all information of the User. Here is the URL for reference.
Before calling this API, you need to create another auth token(which is different from above auth token) for this.
https://graph.windows.net/{your tenant id}/getObjectsByObjectIds?api-version=1.6
I'm using FormsAuthentication mechanizm and auth users via
FormsAuthentication.SetAuthCookie(...);
Can I logout current user from all browsers somehow?
Add a guid parameter inside to authentication parameters. Also save guid to a session table for example like this;
public class sessionLog
{
public int UserID { get;set;}
public string Guid {get;set;}
// ... may be you can add IP, datetime or isSessionClosed etc
}
When login add a row into table, save guid inside the cookie.
Check the user authentication with userID and guid is enabled.
Remove row logout with the guid or remove all with userID for close all sessions.
Technically, that's impossible. The user is authenticated via an encrypted cookie set within the browser. Logging the user out merely invalidates that cookie. There's no way to then invalidate cookies that may exist in other browsers or even other machines.
The only way you could potentially achieve something like this is to indicate in some way, tied to the user's account, that they have been logged out. This could be an additional column on your profile table or some other type of persistent storage medium. Whatever you do, you would then need to look at this when an authenticated user accesses some portion of your site. If they have been previously logged out, you would then log them out again on that browser/machine instance. When they log in again, you would clear whatever you previously set, so that they would remain authenticated. In other words, you have to check and invalidate the auth cookie in each browser when the user attempts to access the site from that browser. There's no way to do anything until the user accesses your site from that particular browser.
You need to store a list of users logged in on an application variable. If a user with that Guid tries to login again you can display a message that they are already logged in elsewhere....
I don't think you can control users session once it has been granted, but you could add logic to deny access to functionality if an attempt to login from elsewhere (I'm not sure why you would want to do it though because logging in from different devices is not always done maliciously).
I have a site (still on localhsot).
I want to authorize the user against Google and get permission to gmail scope.
I get a requestToken
Authorize it
Save requestToken from the queryString into a cookie (?)
(I don't have accessToken by now)
Upgrade it to accessToken
Then what?
I thought to save requestToken and accessToken in the DB with some user guid (?)
Are they both parmenent and uniqe?
Will it help next time to avoid the Upgrade it to accessToken
When the user come back for the second time - how will I retrieve its access token?
You will have to store the access token with the user data, yes. Then you will set the Forms Authorization cookie as normal against their username or id.
When they come back a second time, if they still have the cookie, then they will be signed in as normal.
If their cookie has expired, ask them to log in with their chosen provider (Google) and retrieve the token again. You will then have to search the data to see if any users have that token already, and if they do, log that user in as normal like you do the first time.
If they log in with a different provider, they will get a different token and will effectively be seen as a different user - how you handle this is a separate issue.