I am using auth0 for authentication. I want to fetch all users including their roles. I generated token in auth0 and when I try to execute it in Postman or fiddler tool, Sometimes it's giving roles and sometimes not. Same thing is happening in application also.
If I add manually in app metadata in role property as below, Then information is coming.
{
"authorization": {
"groups": [
"Admins",
"Users"
],
"roles": [
"Admin"
],
"permissions": []
}
}
But I fill, that if I change in authorization tab, It should effect here also.
Below is my code,
var apiUser = new ManagementApiClient("<<Token>>", new Uri("https://<<Domain>>/api/v2"));
IPagedList<User> allUsers = await apiUser.Users.GetAllAsync();
Do I need to clear cache in auth0, If yes then how?
Based on the information you provided it seems that you're using the Auth0 Authorization extension to configure user role information.
If this is the case you should notice that the extension logic is run at login time by the means of a rule. When you have that extension installed you should also have a companion rule; in my account the rule is named auth0-authz and should be the same for your case assuming version 2.0 of the extension.
The impact of this is that the roles are surfaced at the user level at login time, so any changes to the configured roles will be seen next time the user logins.
Note: Since this logic is part of a rule it will only be executed in the context of a login. If users are added to or removed from a group this will only be reflected within Auth0 after this user logs in again (eg: in the user's app_metadata or when calling the /userinfo endpoint).
You're querying the users directly through Auth0 Management API which may lead to the situation where the roles currently stored at the user profile are not up-to-date. If you are seeing stale information then this might be the cause.
On the other hand if your problem is not exactly this one, please provide further information and if possible steps to reproduce. For example, do the roles information show for one user but not the other or does it show for user A in one response, but then if you make another request the response does not include role information for that same user A?
I was not using the authorisation extension, but rather the standard role. So I've had to create the below rule.
More info here : http://isbyr.com/return-user-roles-in-auth0/
function (user, context, callback) {
// Get the user roles from the Authorization context
const assignedRoles = (context.authorization || {}).roles;
// Update the user object.
user.rolez = assignedRoles;
callback(null, user, context);```
Related
I am using Hasura with Firebase and Flutter. When a password-less login/signup link is sent to the user for the first time, I need to intercept the account creation process to add some custom claims before they are automatically logged in. If they are automatically logged in then the custom claims won't be present and permissions will be incorrect.
Is it possible to have a custom Firebase function that I could call to create a "password less" account with the custom claims before I process the magic link? The only call I can see is createUserWithEmailAndPassword which is not the right method...
Another option (less attractive) is to process the link using signInWithEmailLink(), apply the claims to the account using a firebase function, then force a new token (which will have the new claims) via _firebaseAuth.currentUser.getIdTokenResult(true).... would an onAuthStateChanged be triggered on a forced token refresh?
Is it possible to have a custom Firebase function that I could call to create a "password less" account with the custom claims before I process the magic link?
No, it's not possible. Functions can only respond to the creation of a new account after it happened. They can't intercept that process to change the custom claims for a client app that just signed in immediately after an account was created.
would an onAuthStateChanged be triggered on a forced token refresh?
No, it wouldn't. If you force a token refresh from the client app, you will only receive an update from the idTokenChanges stream.
Changing the custom claims on the backend using the Firebase Admin SDK will not force a propagation to the client app. If you want to wire this up yourself, you can do so following something like the process in this blog post. The backend will somehow have to push some data to the client app to get it to force refresh the user's token to take effect immediately.
For anyone that lands here, in the end I used Hasura Claims Map https://cantaspinar.com/easier-authentication-with-hasura-jwt-claims-customization-firebase-auth/ to apply default claims. This means all people who log in get the "user" claims by default, unless there are any claims applied on firebase which will then be used instead.
My claims map looks like:
"claims_map": {
"x-hasura-user-id": {
"path": "$.user_id"
},
"x-hasura-default-role": {
"path": "$.['https://hasura.io/jwt/claims'].x-hasura-default-role",
"default": "user"
},
"x-hasura-allowed-roles": {
"path": "$.['https://hasura.io/jwt/claims'].x-hasura-allowed-roles",
"default": [
"user"
]
}
}
}
That's my question. I am using Hasura, and defining 'user' permissions.
Users are of course allowed to modify their own information, and not allowed to insert new records into my users table.
But when they signup, they should be allowed to insert themselves. So how can I define this permission?
To make my scenario more clear:
I have a React app, that uses an external OpenID provider. So a new user signs up there, and the provider returns a JWT to my app, containing a user I've never seen before.
My app does not know that, it just uses the access token to send to the Hasura backend to retrieve further info about this user, using the 'user' role. But it uses a query which will automatically insert the user if not found.
There's really not a safe way to allow sign-ups without involving a backend service. It is a very bad idea to allow anonymous inserts into your user table, even if you added a unique constraint against a user ID or email address.
If you have the option of using NextJS, see the Hasura example for configuring NextAuth. This works by configuring your app with a protected API route that uses your Hasura app's ADMIN_SECRET to insert new users who have authenticated with a third-party.
If NextJS isn't an option, Hasura's Auth0 example similarly uses a callback method to insert an authenticated user if they don't exist.
In the user table, for the user role, you need to add a permission with custom check. And the check should be user_id equals x-hasura-user-id.
{"id":{"_eq":"x-hasura-user-id"}}
For non-logged-in users, leverage the anonymous role by setting the permissions that make sense for your use case: https://hasura.io/docs/1.0/graphql/manual/auth/authorization/common-roles-auth-examples.html#anonymous-not-logged-in-users
Edit after the comment:
Ah, I see. When the user comes to your app, your app goes and retrieves some data that it expects every user should have (for example perhaps the user info store on the user table). But since it's a new user, this info is not there.
At this point, your React app knows that:
there's someone with a legitimately signed JWT cookie (use a library to verify the signature) and
there's no user info from the backend. Therefore, the React app shows
a "Welcome new user, wait while we're setting up your account".
Then
the React app makes a mutation to a signup Hasura action you'll
prepare. Once that returns, you proceed as usually (redirect the user to their home page).
use hasura action handler instead. Inside your handler, do a check if the user already exists or not. If not then insert a new row.
To add ADFS 3.0 authentication in our SPA we use the javascript sample and one (wsfed) external identityprovider, and we also add a local api for the SPA client
We also added a custom view to the login process, where the user could "Select WorkingContext" and we could set an additional claim.
Problem: How to add and retrive that additional claim?
Since we simply need the a few of the claim from ws federation, we've made a super simple callback where we just do the following (I'm answering the questions from the docs)
Handling the callback and signing in the user
inspect the identity returned by the external provider.
Yes, we get correct claims from wsfed
make a decision how you want to deal with that user. This might be different based on the fact if this is a new user or a returning user. New users might need additional steps and UI before they are allowed
in.
No additional steps required
probably create a new internal user account that is linked to the external provider.
No, we don't need the user, we just need the a few of the claims from wsfed, so we just return a TestUser based on the wsfed sub in FindUserFromExternalProvider
store the external claims that you want to keep.
Do we need to store the claims, will the claims not be embedded in the jwt token, and the token simply validated?
delete the temporary cookie
ok
sign-in the user
Here we would like to show a custom ui where the user should select a "workingcontext", and we could add the "workingcontext" as an additional claim.
Assuming the above is valid, how can we in step 6 add the extra claim?
await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.ClientId));
doesn't seem to give any ways to add claims.
This is how we try to pass the additional claims through the login process:
var isuser = new IdentityServerUser(user.SubjectId)
{
DisplayName = user.Username,
IdentityProvider = provider,
AdditionalClaims = additionalLocalClaims
};
await HttpContext.SignInAsync(isuser, localSignInProps);
We just need to implement the IProfileService, that's all.
I am setting up an instance of WSO2 API manager, and want to give developers access to the API "store" pages by linking it to my existing OpenID Connect identity server (OpenAM). I've added the OIDC configuration into the store configuration file (wso2am-2.6.0/repository/deployment/server/jaggeryapps/store/site/conf/site.json) with all the details of the authorise, token, userinfo endpoints, etc.
When users click login in the store, it is correctly redirecting them to OpenAM to login, and passing an access token back to the store app. I've also ensured some of the required claims are returned from the userinfo endpoint (like preferred_username). I'm also returning a "groups" claim listing the groups the user should be in "subscriber" for example.
The claims I'm returning from userinfo are:
{
"address":{
"formatted":"My House"
},
"given_name":"Danny",
"family_name":"Developer",
"name":"Danny Developer",
"preferred_username":"Danny Developer",
"groups":[
"subscriber"
],
"email":"adam.hatherly#nhs.net",
"sub":"developer1"
}
However, whatever I try with claims and group names, the store still gives the error message "User is not permitted to log in to the Store.". I assume there's something else I need to add in either the access token or userinfo endpoint
claims list to make the store app accept the user, or some other config in the store or carbon console?
The reason for the user login issue is that the user does not have relevant permissions to log in to the store. User needs to have internal/subscriber role assigned to it. Since the user is coming from OpenAM and APIM does not have any information to authorize it, login fails.
For this either you should share the user OpenAM user store with APIM (say a shared LDAP) and assign users with internal/subscriber role or use a custom code to add the user to the APIM user store and assign the role.
Another easiest option is to create a user in APIM side (add a dummy password) with subscriber role. but this is not a suitable solution if you do not know all the users
I've implemented my own user login and logout system by just setting a session variable and checking it in my main template so I will display a login screen if not logged in and display the app if I am logged in (this is typically how I did things with PHP).
I did this instead of using any of the built in user account systems because I needed to implement my own login password check to a legacy web service.
Because of this, it seems I'm running into trouble now because things like allow/deny rules for my file uploads don't seem to have the userId:
download: function (userId, doc) {
console.log("userId ", userId);
return true;
}
This prints : userId null
So, I'm unable to implement any logic here based upon whether the user is logged in or not.
So, is there a way for me to tell the meteor accounts system what my userId is when I perform my custom login? --- which I presume would then make it available here in the download allow/deny rule?
EDIT: I've had to implement a custom login handler with Accounts.registerLoginHandler. Doing this caused the meteor system to set the userId in the built in accounts system, which allowed it to be passed into the allow/deny functions... but my question still stands. I would like to know if there is a way to alternately provide some information (say, the values of a session variable) to these allow/deny rules instead of being limited to using the built in accounts system.