MVC 5 current claims autorization and updating claims - .net-4.5

I have 2 questions regarding the claims:
1) In .Net 4.5 and MVC 5 how does the microsoft implements the autorization, when you set on controller AuthorizeAttirubte, does it check the database to get the user role? Or it uses the claims?
I've read somewhere that microsoft uses database each time to verify the role, and they advised to write a new AuthorizeAttribute to implement claims authentication.
This is the article i'm talking about: http://kevin-junghans.blogspot.be/2013/10/improving-performance-of.html
Or is it outdated and now microsoft uses the roles in claims?
2) Second question regarding the update of claims:
Imagine when user logs in, I set his display name as a claim. The user has ability to change his display name, so he changes it, but he still sees his old display name, untill he reasigns in the webiste.
Would it be correct to somehow update the claim ....? And how to do it?

The authorize attribute is using things off the User.Identity like IsAuthenticated/IsUserInRole, which indirectly looks at claims. Database access is based on when the sign in cookie is refreshed as opposed to the authorize check, so its orthogonal.
Claims are updated when the sign in cookie is generated (database hit). To force an update of the claims, you can just resign in the user which forces the update.

Related

What is the best approach to stop your platform's users to "sniff" the frontend requests to backend and modify them?

So I have a platform that works like this: Users can create accounts by logging in with their Google (I USE AUTH0) and then they can create "Projects" which contain lots of other unimportant stuff regarding my current problem (like todo lists, ability to upload files etc; they can also Edit the project by changing some of it's attributes like name, description, theme and so on). There is a home page where everyone can see each other's projects and access them (but not upload files, change the tasks in the to do lists; this is possible only by the person that owns it).
By using a tool like Burp, people can see the request made from frontend to backend, for example when accessing one of the projects, and modify it on the fly.
This is what it looks like inside Burp when they access one of the projects:
As you can see there is a Get request to /projects/idOfTheProject; they can replace the GET with DELETE for example and they will successfully delete it; they can also see what is sent to the backend when a project is edited (name changed, description, thumbnail picture etc) and change anything they want about it.
How should I prevent this?
What I've looked at so far:
a. JWT - Probably the best fitting for my situation, but required the most work to be done (as I already have my platform almost finished with no such a security measure implemented yet, so I may need to rewrite a lot of things in both backend and frontend)
b. Sending the user's id that initiated the action as well to the backend and verify if it has the necessary privileges - the worst solution as users can access each other's profile and see the id, then just change another field in the request's JSON
c. Have a sort of token for each user and send that instead of the user's id - in this way somebody can't get your token by just looking at the communication between frontend and backend (only if it is using YOUR account). That token should be taken maybe somewhere from the auth0 when they create their account? If they provide something like that; or I can just create it myself and store it alongside the other user variables. You would still see the requests in plain text but even if you modified something you would still have to "guess" the owner's token, which will be impossible.
For frontend I use NextJS and for backend Flask.
Thank you in advance!
The TL;DR is that you don’t. A determined user will always be able to see what requests are being sent out by the code running on their computer and over their network. What you are describing when asking how to prevent people from “sniffing” these requests is security through obscurity, which isn’t actually secure at all.
What you should do instead is have an authorization system on your backend which will check if the current user can perform a given action on a given resource. For example, verifying that a user is an administrator before allowing them to delete a blog post, or making sure that the current user is on the same account as another user before allowing the current user to see details about the other user.

Keycloak 15.0.2 - UserFederation and AccessToken mismatch on first run

As the title says, I'm developing a Custom User Storage Provider (here forth SPI) with Keycloak 15.0.2.
I’m having trouble sorting an issue where the very first access token that is issued, does not match the expected format (is missing some fields) but also seems to be issued for a different user, if I am to judge only based on the sub field of the AccessToken generated.
To ease reproduction of the issue, you can find my repository on Github here with a complete sample FE and BE along with the keycloak configuration. I also included samples of the result tokens, jwt.io links and logs on LOGS.md file on the repo.
I think I understand why this mismatch is happening, though.
Due to the fact that I start with an empty collection of users on keycloak, I need to create the users on their first login. All I have to start with is their email address which is input on the login screen.
With this information, I setup a “temporary” Federated User until I get the user data from the “real” IDP on the isValid method (where the user actually logs-in into the third party IDP) and then get his details, which are then used to fill a more complete FederatedUser profile and store it on the userLocalStorage.
It's basically this logic (it's all also explained in comments in the repo's code):
Create an adapter/model based solely on the email from the login form to be used temporarily.
Proceed with normal operation.
Then on the isValid() method:
login the user through the REST call to the backend and get the JSESSION token
on a separate call, call the Current-User REST endpoint to get user details and map them to a Dto object
create a new adapter, based on the Dto object (which already contains all the user details like name, phoneNumber, etc) and from that, add to storage as a ksession.userLocalStorage().addUser() user and enrich with custom attributes (to later be mapped into the AccessToken)
when (and if) added, clean cache with ksession.userCache().clear()
Proceed with normal operation
However, I think that the ID/model of that first temporary user is the one that is actually being used during the issuance of the first AccessToken that is generated and is being cached somehow on some other class which then generates the AccessToken with missing information/not the correct user model.
When I reload the page (forcing it to go through the login flow again), I then get the correct AccessToken with all the fields I expected the first one to have. I also noticed that the sub of the tokens are different, and this is what leads me to this conclusion.
Does this flow/conclusion seem correct to you?
And more importantly, how can I fix this?
I have no way of getting all the user data at first or a way to import it (ideally, I didn’t even wanted to Federate, just some ReadOnly data would have been enough if I could modify the AbstractUserAdapter attributes).
Can I somehow access the CredentialInput outside the isValid method?
That’s the only way I’d have to grab all the user data since the beginning.
I’d really appreciate any help you could spare. The reproduction code is just a clone/docker up away and will replicate the issue perfectly.
Please help me figure out how to make sure the token get properly set/issued the first time around
Thanks

Use token's username in policy path

I have a Vault server where users will log-in using Userpass auth method and making use of kv secret engine.
The structure is like below -
-- user-kv
-- u1
-- u1-secret1
-- u1-secret2
-- u2
-- u2-secret1
-- u2-secret2
-- u3
-- u3-secret1
Here, u1, u2 , u3 are username of the users logged in using Userpass auth.
Now, for each user, I want to allow access to his path only. His path refers to this structure user-kv/<username>/ For example -
u1 --> user-kv/u1/*
u2 --> user-kv/u2/*
u3 --> user-kv/u3/*
and so on....
I am currently doing this by creating a separate policy for each user and and assigning it to him. I believe this is not the right way as when number of users grow, it would be difficult to maintain.
Is there a way to specify the logged-in user's username in the path in a policy. Something like -
path user-kv/{{username}}/* {
capabilities = ["read", "update", "create" ]
}
I have tried with templated policies but it doesn't work.
path user-kv/{{identity.entity.metadata.username}}/*
path user-kv/{{identity.entity.name}}/*
I can do something like user-kv/+/* but that would mean every user would have access to other's path.
Can anyone point out a more elegant way or provide links for further research?
I don't have a Vault running at the moment to check this out, sorry, but I believe that the templated policy you tried should work. The key is to create an identity that is associated (via an alias) with the userpass user. It's been a while since I've done this, so I can't remember the details, but check out the docs: https://www.vaultproject.io/docs/secrets/identity
The basic idea you have is feasible, but it is a lot more complex than that.
First, some background
A user in Vault is called and entity. When you authenticate for the very first time, a Vault entity will be created automatically, unless one already exists.
Obviously, you had to login with some auth backend. Let's say you used LDAP. Whatever you actually used is irrelevant for this discussion.
When you authenticated, an entity alias was created to tie this specific user in that specific auth backend to an entity.
With that background information, here is where it gets complicated.
Vault supports multiple auth backends, and you can tie them all to a single entity. So if our user prefers to login with the Github auth backend, he still keeps his access rights (aka policies). That happens because you would have set the entity alias prior to the user logging in.
Now even if you are using a single auth backend, Vault will still behave like that, because it can't know what the future holds.
Now back to your question.
To allow a path to represent a user, you must use the syntax described here. But to use them, you need to know in advance either:
The name of the entity
The name of the user in the auth backend
Option #2 will also require you to assign multiple policies (one per auth backend). I suggest you go with option 1.
The easiest way to acheive what you want (even if it not that easy) is to provision entities before they log in, and associate metadata to it.
Say you add the metadata kv-user=u3 to the entity that represents the user named u3, Then use {{ identity.entity.metadata.kv-user }} in your policy file.

specify user id when creating user in keycloak

I'm investigating a migration process from a legacy system into keycloak. Based on some of the ideas here: https://github.com/Smartling/keycloak-user-migration-provider we're looking to create user accounts in keycloak at the point of login by looking up user credentials from some dedicated endpoints on our legacy system.
As part of this, I need the user ID to remain the same as it was in the legacy system.
Is it possible to create a user with a specified ID rather than relying on keycloak to auto-generate it?
Running into this issue when attempting to create users via the API, I looked into the code for the users service. It looks like it is currently not possible to set the user id due to how the user is created.
From the code in https://github.com/keycloak/keycloak/blob/master/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java specifically on line https://github.com/keycloak/keycloak/blob/7cfe6addf01676939206e034a87c791460031032/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java#L115 the user is first created using the username, then updated. I believe id is not an updatable field. Thus it is not currently possible.
Checking the api I see it is now possible to add an optional "id" field in the userRepresentation object that you pass to create a new user in keycloak.
Find more information here: https://www.keycloak.org/docs-api/5.0/rest-api/index.html#_userrepresentation

Allowing a user to update their own profile using the REST API

I have been experimenting with the REST API using my logged in user account's token to then make PUT requests on my user record to update some custom attributes.
In order to get to this work I had to grant my user account the manage-users role in Keycloak, prior to this I was getting forbidden responses back.
I can now make the PUT request successfully, and after logging out and logging back in I can see the updated attributes I set in my PUT request.
But I have now allowed my user to be able to manage all users in my realm, which I dont want to allow.
Instead I only want to be able to update my own account details.
I know the user can view their own profile and make changes on the Keycloak provided screens. But for certain custom attributes I want to be able to do this from the client side application they are logged in to, so using the REST API but not granting them a role that could allow them to update other users details.
Is this possible?
According to the User section Keycloak's Admin REST API, this is not possible.
One solution would be for your client app to send the update request to a backend. The backend will verify that the update request is legit (aka the JWT is verified and the update does apply to the user requesting the change).
Another solution would be to theme the User Account Service's screens to add input fields for your custom attributes, as the documentation says that:
This screen can be extended to allow the user to manage additional attributes. See the Server Developer Guide for more details.
The second option seems the more secure. I hope that helps.
This seems to be possible with the Account Management API.
Unfortunately, I didn't find any official documentation about that. However, there's an example in Keycloak that demonstrates how to do it.