How to update a custom and dynamic claim value for a logged is user from the application - single-sign-on

I have a custom policy for my Azure B2C, where after the authentication, user need to select a code and once selected correctly user is successfully redirected to the application he was trying to log in.
From the application I can get the code as claim.
Now, I need to update this code, so that his claim gets updated and any other application he logs in through this b2c - remains same.
What will be the user journey for this claim update for the logged in user ?

Related

Azure DevOps OAuth2. TF400813: The user is not authorized to access this resource

I have implemented an OAuth2 app for Azure DevOps. My website takes user (User A) to authorize the app using the below URL.
Step1
https://app.vssps.visualstudio.com/oauth2/authorize?scope=vso.code_full (skipped the other parameters)
The above URL works fine and returns with a code+userInfo after user authorization. Now I get an access token passing the code returned from the app using the below API call.
https://app.vssps.visualstudio.com/oauth2/token
I can further fetch all the organizations associated with user's (User A ) account using the below API call
Step2
https://app.vssps.visualstudio.com/_apis/accounts?api-version=6.0-preview&memberId=xyz
Now I want to fetch the repositories inside a particular organization. For that I make the below API call.
Step3
https://dev.azure.com/**organization_name**/_apis/git/repositories?api-version=5.0
The avove URL works fine and returns to the repositories inside the specified organization.
Everything fine so far.
Now another user (user B) is trying to connect with my app and he can authorize the app and my application can fetch the organizations under that authenticated user's account. e.g. everything fine until step2. But it fails on step3 e.g. it fails to fetch the repositories inside user's (user B) organization. The API call in step3 returns with following error
TF400813: The user is not authorized to access this resource.
kindly help.
To further clarify, I suspect that issue is with Authenticated user (user B ) , as the whole process works fine for one authenticated user (user A ) but fails for the other user (user B). So there must be something different with second authenticated user. But I am not sure what is it as I am not an Azure guy.
Also Note that when I am logged in with User A or User B , I can view my organizaions/projects/repos , also I can add/delete organizations/projects/repos. (I am the organization Owner)
Then If I am able to view my organizations/repos with a logged in user , and the same user is authenticating the OAuth app then why the Access token produced by the user is not authorized to access the repos in the User B's account ?
I have found the missing part here.
It is that I have to go to the organization's settings like at the below URL
https://dev.azure.com/my_organization_name/_settings/organizationPolicy
and check the first check box under Application connection policies which is Third party application acces via OAuth
by checking in this option , I am able to fetch the repos under User B's account as well.
It's a shame that Microsoft has no documentation for this. Another reason to hate Microsoft products.

How to create a user from a id_token with Spring?

I am building a SPA with a spring on the backend. I am working on signing in with Google, most of it is working already: got the id_token with the implicit flow in the frontend and I sent it and verified it on the backend.
I want to have users with roles and manage that locally (so, no adding info in the oidc provider). What are the options to go from the id_token to having an authenticated user in spring? I did not find any example doing that link manually (id_token-spring_sec_user).
I have checked several sources like the Spring Security 5 presentation at SpringOne https://www.youtube.com/watch?v=WhrOCurxFWU, several SO questions and posts on okta's and auth0's blogs but I am still missing the link.
You will have to create your own (application) specific roles.
Use these steps :
Get authenticated from Google
Access the profile section from google (username, name etc )
Use your own user table to store this info
Create admin APIs in your own system and assign your app-specific roles to the user.
When you login again you will authenticate against google login/password and roles specific to your application .
Create an account or session with the id_token
Check if the user is already in your user database. If so, establish an authenticated session for the user. If the user isn't yet in your user database, create a new user record with default role from the information in the ID token payload, and establish a session for the user. You can prompt the user for any additional profile information you require when you detect a newly created user in your app.

keycloak, user registration. How to add the role?

I have an app secured by keycloak. Going to a secured page brings up a keycloak login page and the correct user/password gives the expected results.
Within the client, I have switched on user registation. So now the login page shows a register link, which displays another keycloak page allowing the user to register with name, username, email.
This "works" in that the user is added to the keycloak user database. But the application displays the error page because a role is not mapped to that user in keycloak.
What I would like to happen is to be able to add the new user to the apps own user database, associate a role with the user, perhaps do some verification of the user.
So I don't really know what keycloak is sending back to the app except that it eventually leads to /error. Is there a way to tell keycloak after a new registration contact this url where things can happen within the app?
I came across similar scenario and the way I solved it was by enabling a default role to the newly added user.
This role can be changed later on but with a default role in place, your flow will complete.
There are 2 ways to assign a default role in keycloak. With both these configs, whenever a new user is registered even from external service providers, they will be assigned this default role:
Assign a default role directly to user:
Assign a default group to user & map a role to that default group
Please note that Default Group & Role names in above are my own and they are not predefined in keycloak.
After logging in to Keycloak admin console --> roles -> go to 'Default Roles' tab and add the role from available section to default realm roles section and save...Now when a user is registered, it will have the role assigned .

Play Framework - Disconnect an user

I'm doing a Scala - Play application and I want to disconnect an user when an admin change his right. For exemple, is an user is logged and an admin upgrade his account to the admin type, I want disconnect this user.How can I do that ?
If you stored the userId in the Session you will need to add the rights of the user in the Session.
So that when the user connects, you can check his rights from the session to the ones in your database. If they don't match you can redirect the user to the login page.
just to cover all the bases since the answer here depends specifically on how your application determines if a user is logged in:
if user auth is done with a token generated by a secret that is stored on your user model and checked for validity on every request, you can generate a new secret for the user and all existing tokens will become invalid.

GWT : How to prevent client-side state from being cleared when a redirection (for e.g : OAuth2) happens?

I am implementing OAuth2 authentication for one of my GWT projects (let's call it GWT-app). The application responsible for authentication is a third-party application based on Spring Framework-3.1.2.RELEASE and uses its OAuth2 implementation included in Spring Security-3.1.3.RELEASE (let's call it OAuth-app).
GWT-app is a management application for managing user and stores. Each user has one or more manager accounts. A manager account may have one or more stores attached to it so that he can manage them altogether from one screen of the GWT-app.
It means that the user may potentially have to authenticate many times through different manager accounts to display stores by manager account on the app.
So on the StoreManagement.java page of my GWT-app, I have the following :
private final Map<String, ManagerAndStoresProxy> managerAndStores = Maps.newTreeMap(Ordering.natural());
after authentication, this map should be populated with Manager name and a List of attached stores for each.
OAUTH2 FLOW
The Authorization-code flow is used for authentication. When GWT-app wants to authenticate someone, it redirects the user to a login page on OAuth-app. The user enters his credentials and will be presented with an authorization page asking him whether he wants to allow GWT-app to access his information. If the user clicks on authorize, he is redirected back to the GWT-app with an access token.
THE PROBLEM
The only issue is that since GWT-app is redirecting the user to another application for authentication, the first time the authentication works and the map is populated correctly but if I have to authenticate another account then the previously authenticated account is cleared and can not be retrieved because of the redirection.
The question is then : how can I proceed to persist this map and retrieve it back when a second (third, fourth and so on) authentication flow is over (i.e after the url-redirection of OAuth-app).
WHAT I HAVE TRIED SO FAR
What I did so far is that when the user wants to proceed with authentication from the StoreManagement.java page, he is presented with a popup redirected to the OAuth-app authentication page. The access token is then retrieved from this popup but I have to send it back to the parent window (i.e StoreManagement.java page). This can be done via a HTTP GET parameter but this method reloads the parent page and the result is the same: the previously authenticated account is cleared.
QUESTION
What is the best way to handle this situation without clearing the previous context and without requiring any server-side session mechanism whatsoever ?
The root of the problem is using the authorization code grant; the implicit grant (aka client-side flow) would be a much better fit.
If your app is not limited by old browsers in terms of compatibility then you can try to store all necessary things in HTML5 Web Storage.