How to authorize user to update his own user data - fusionauth

Based on the information given at https://fusionauth.io/docs/v1/tech/apis/users#update-a-user it seems that any API key that allows access to this endpoint can update any user record.
I am missing a method of authorization based on a JWT for this endpoint so that any user can update his/her user record.
What is the recommended practice to handle this?

FusionAuth does not currently allow you to call the Update User API with a JWT issued to the user you're trying to update.
There are a couple of reasons for this. the first is that not all implementations would agree this is a safe operation for an end user to perform. The second is that because the custom data on the user and registration objects will be indexed by Elasticsearch. Elasticsearch creates a dynamic schema based upon these values which means it will expect the schema not to change.
For these reasons, and perhaps others, it is much safer to allow an API written by the FusionAuth implementor to handle this process.
That is all to say, you will want to call the Update User API on your end so you can control what is updated and perform any necessary validation on custom data.

Related

How to manage user updates and deletions in OIDC and SPA architecture

i am making a set of applications that share a common oidc provider (in my control), where the users will be created.
One of my applications is a stateless SPA "meeting" app where you can schedule meetings with other users, and you login purely by an OIDC token.
I am having a hard time thinking a strategy about the following
Should the "user" details be stored in the meeting app after a login? So let's say user A exists in the provider, then enters the meeting app. Should i save user A in the meeting app DB?
How to handle change of user details? Let's say user A changes name to User B in the provider. Until he logs in again, all the other users see him as User A still in the "contacts" list. What is the usual practice for solving this?
How to handle deletions in the provider. I need someway to signal that "deleted in provider -> deleted in app". Should i constantly poll the provider and get any missing users, create a push system, or is this just unneeded?
Thanks a lot in advance
That's actually a very good question and rarely explained well in online articles. Hopefully the below detailed notes help you with your solution. I have answered your questions at the end.
OAUTH USER DATA
Typically the core user data such as name, email etc belongs in the Authorization Server. It contains Personally Identifiable Information (PII) and changes are audited there. This is explored in further detail in the Privacy and GDPR article.
DOMAIN SPECIFIC USER DATA
This might include fields like a user's application preferences, and you may end up with data similar to this in your APIs:
Field
Description
id
A database surrogate key for the user
subject
The subject claim from an OAuth access token, which is typically a GUID or something similar
archived
A boolean flag set to true when a user is active in the app
field 1
A domain specific value
field 2
A domain specific value
To get OAuth user data within your applications your APIs can call the Authorization Server's SCIM 2.0 endpoint as described in this User Management article.
AUTHORIZATION AND ROLES
Interestingly, roles and application specific rights could be stored in either of the above data sources. You may want to start by putting roles in the OAuth data, but for cases where they are very domain specific and change often, I have found that storing them in my own API data works best.
DOMAIN SPECIFIC USER DATA AND ACCESS TOKENS
Sometimes you need to include domain specific user data (which might include roles) in access tokens. This Claims Article explains how claims can be looked up from external APIs during token issuance. This typically involves a REST call from the Authorization Server to one or more APIs, providing the subject value for which tokens will be issued.
CONSISTENT USER IDENTITY IN YOUR APPS
A user can potentially authenticate in multiple ways, such as default password / corporate login / social login. You may need to use some custom Account Linking logic to ensure that the subject field in the access token gets the same value in all cases. This prevents you ever creating duplicate users within your application.
USER INFO CHANGES
These are typically made by end users within an application screen, and your APIs then call SCIM endpoints to update the core OAuth data. A common case is when a user changes their name and / or email, eg if the user gets married. Note that the subject value remains the same after this edit.
USER ADMINISTRATION
In scenarios where corporate assets are used, an administrator typically provisions users, either individually or in bulk. This can be done via the SCIM endpoint. In some cases administrator actions may need to save data to both data sources - eg to create a user and set roles + application preferences.
USER INFO EVENTS
Sometimes your application needs to know about a user info event, such as new, deleted or changed users. This can be managed via Event Listeners, where an extension to the Authorization Server calls back your domain specific APIs when a user edit occurs. When a user is deleted in the OAuth user data you might then update the user's application state to archived.
DATA MIGRATIONS
Finally it is worth mentioning that the above also supports migrating to an OAuth architecture or between providers:
Get a combined view of the user data before migration
Insert all existing users into the new OAuth system via SCIM
Update the combined view of the user data with new subject values
Update your domain specific data with new subject values
SUMMARY
So to answer your questions:
Aim to avoid this because it adds complexity, though in some cases you may need to denormalise for performance reasons. The OAuth user data should remain the source of truth and the only place where edits occur to PII data.
Your meeting app would need to join on the OAuth user data and domain specific user data and present a list. This would probably involve caching a combined view of the user data.
See Administrator Events above. Your API should be informed of OAuth user data changes via an event, then your SPA would get current data on the next refresh.
When implemented like this you end up with simple code and a well defined architecture. Some providers may not provide all of these features though, in which case you may need an alternative approach to some areas.

Use WSO2IS to configure user access to entities

I'm trying to implement WSO2IS for authorization. My understanding is that in the WSO2 realm, the concept of a permission broadly restricts a user's access to an action, or a resource. So, for instance, if my app is a bookstore, I could configure whether a user has "read" access to authors at large, and toggle their access to the GetAuthors() endpoint. However, I need to configure a user's access to certain authors. Is there a way I can store a whitelist of authors on a per-user basis? What I'd like to accomplish is to have a user call a GetBooks() endpoint and return only the books written by the authors that the user can access.
It sounds like one possibility is to store this information in an external datastore, and implement a custom PIP to read from that datastore.
Another possible option would be to create a custom attribute on the User type and store the whitelist of author IDs in an array on each user.
Is there a better way to do this? I'd prefer not to implement a custom external datastore just to store relationships between users and entity ids. Is it possible to do this with XACML and policies? Is it possible to have WSO2IS stick this information on a claim that is returned to my controller so that I can limit my underlying query based on the user's whitelist of allowed entity IDs?
AFAIU you need to maintain a claim to track the accessibility for reading. You can easily create a custom claim to track it by following the article[1]. In this way, you can refer to the custom claim at the controller to make further decisions.
You have to update this claim value for each user. For this, you can use SCIM API[2] by following doc[3] to extend the SCIM endpoint for custom claims.
[1]https://medium.com/#inthiraj1994/lets-add-a-custom-claim-to-oidc-in-wso2-is-d871e418d6b0
[2]https://is.docs.wso2.com/en/latest/develop/scim2-rest-apis/#/scim-20-api-definition
[3]https://is.docs.wso2.com/en/latest/develop/extending-scim2-user-schemas/#extending-scim-20-user-schemas

Grails 3 and Spring Security - authenticate user in filter

I'm developing a Grails 3 web-app powered with Spring Security plugin, which already makes large use of #Secured annotations to protect controllers and actions according to the privileges of single logged-in users.
The login is currently managed via the usual username/password pair.
Now a new requirement came up, involving a custom request header, having as value a sort of 'authorization token':
this token identifies a group of users (let's call it team)
if this token is recognized as valid, matching against DB, then the whole application should behave as a predefined user (let's call it John, part of the team) was logged-in. In this sense it should act as a pre-authentication. This user will have his own roles, so the application will respond accordingly, as if John would had logged in with his own username/password.
if the token is not recognized, 401 status must be returned.
if the token is not passed, the application must have its current behavior, to the token management should be considered optional must not impact the current implementation at all.
I considered defining a custom filter (I also took a look at this post, which however has different requirements), but I cannot even determine:
the feasibility of this task
whether or not filters are the best approach (but I guess so as Interceptors are triggered too late, and I need some additional logic to be evaluated before Spring Security comes into play)
possibly, the best filter to extend
So any suggestion is welcome! Thanks in advance
Not an expert on this, but I would implement a custom UserDetailsService and set the authorities based on the token condition. You might also be able to do it in an AuthenticationSuccessListener.

CRUD only for the organization the user belongs to

Background
I'm building a application where all users belongs to a Organization. I only want the user to be able to Create/Read/Update/Delete records in the Organization they belong to.
I'm using sails, but I'm looking for Connect/Express-based, or a standalone answer as sails-permissions node module is unmaintained.
Question
How can one implement a authorization that allow CRUD only for the organization the user belongs to?
We are also not relying on sails-permissions. In our app, users can be members of multiple orgs.
We are using auth0 for all authentication activities, i.e. every request must include a jwt that is included in the request header. The jwt includes userId, orgId and role.
Sails policies decode the jwt and attach userId, orgId and role the the req object for all later checks.
Every model has the property orgId - we are using MongoDB.
Every controller, db operation, etc. adds this verified orgId to the query. Actually we have a small pipeline preparing the query: we add the orgId, in update cases we filter out unwanted property updates, etc.
This approach does not require additional db calls for separation of tenants.
Some models have specific access requirements per individual RECORD. Here we store allowedUser properties (one for read, one for update, etc.) on exactly this record and we extend the query once more so that only records are returned or updated or Xyz where the current user is included in the applicable allowedUsers property.
This approach also does not require additional db calls. This leverages MongoDB-specific query features, though.
We currently do not have ACL-like requirements which would be right between the 2 approaches I described above (re access control granularity).
You'll need to intercept each request using middlewares
combine them with a role system by checking if a certain token is present on request headers and in a acl map and finally, if the token is present in the acl map, see which permissions are related with this token.

Spring data REST & data security

So I have a nice set of Spring Data REST repositories and they work great. Now I want to secure the data they produce. The URLs to the repositories are secure, in that, only an authenticated user has authorization to call them. However, only data in the database associated to the user should be sent to the client.
I have implemented an interceptor which gets called prior to the repository call which contains information about the logged in user, but I'm not sure how I can ensure only data produced by the REST call is data associated to the logged in user.
Obviously the client is coded to only make calls with links associated to the currently logged in user, but a user could simply change the URL to look at data they are not supposed to see.
Has anyone solved this issue?
Thanks,
Cory.
If you're using spring security, you can insert additional filters (ideally, based upon the url, or domain object.)
If you want object level security, you can still do the same thing, but you're going to have to somehow specify who/what role is allowed to access which domain object/id combinations, in either case, I don't think spring data rest handles (or should handle) any of that.
Spring Security's #PostFilter allows you to filter collection or arrays on the basis of authorization.
#PostFilter ("filterObject.owner == authentication.name")
public List<Book> getBooks();
Check these documented examples
https://github.com/spring-projects/spring-data-examples/tree/master/rest/security