Keycloak Access Token - How to get it without password? - C# - permissions

In my Blazor Application, I'm using Keycloak to manage user authentication and authorization. One of the features in my application consists of allowing the users to see a list of all Users Registered in the application. To do that I need to access "realms/realm/users" Keycloak API, but in order to do that I need to get the access token, and to do that I need to pass a 'username' and 'password' to HTTP POST request. How I am supposed to send user's password in request since I don't have access to that? Any thoughts?
My idea was to create a 'bot' user that would have this permission only and get the token for that 'bot' user instead of the actually logged in user, but it doesn't seem right.

Related

Manage Cognito User Pool using JWT

I have a Node.js lambda API that's called by an authenticated user. The user is able to access the API passing a valid JWT token. Now I'd like to interact with Cognito User Pool to change the user's email, password and etc but I haven't figured out how to achieve this using just the JWT.
I've made several tests using amplify-js and amazon-cognito-identity-js
You can reset the user's password by calling an admin API call, not through the JWT token. https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminResetUserPassword.html This will prompt the user for a new password.
This API call is to set a password for that particular user https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminSetUserPassword.html but I prefer the first option.
In order to change user attributes (such as email, birthday...), use https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminUpdateUserAttributes.html
So all these are done using the Cognito Service inside the Lambda (not to be confused with the JWT tokens).

IdentityServer4 Password Grant

I've stood up an instance of identityserver4, an API project, and a UI.
The workflow is as follows:
User visits the UI.
User provides user name and password to UI.
UI sends credentials to back of web app, which uses a password grant to authenticate the user with IdentityServer4.
IdentityServer4 returns a token.
Token is used to identify who the user is to the UI and that the user has access to certain sections of the site.
When the user needs to do something within the site, the token is passed to the API via bearer auth.
The password grant isn't negotiable, as this is a first party app and it makes no sense to redirect the user away from the main site.
What's the proper set of middleware to use for this? Should I just use a CookieAuthenticationMiddleware and attach the token as a claim? I'll need to access the claims from HttpContext.User claims. Do I need to use IdentityMiddleware?
You can request identity scopes using the password grant type and use the userinfo endpoint to resolve them to claims - like in this sample:
https://github.com/IdentityServer/IdentityServer4.Samples/tree/dev/Clients/src/ConsoleResourceOwnerFlowUserInfo
And yes - you can use the cookie middleware to persist those claims and the access token for later usage.

What to do after getting oauth2 token?

I'm trying to implement a "Sign in with ..." authentication system.
I've read several posts and articles on oauth2. Everyone that I've read stops the discussion or tutorial at getting the access token and possibly logging in the user for that session.
I understand that and can implement that part. Here's what I don't get:
When the user leaves the site and doesn't come back for a week, but they're still logged into the client, how do I log them back into my app? I know you save the access token to the DB, but how do you use that to log them back in?
If they're logged out of the client, how do you redirect them to the sign in page of the client. It seems that every time I try to log back in I'm asked to allow or deny the app again. I know that isn't standard, so how do I fix that? What do I send the client so that it knows that the user has already authorized the app?
I don't need a code sample unless someone knows of an article, what I would really like is just a high level overview of what to do with the access token after I have received and saved it.
Thanks!
EDIT:
I understand that OAuth2 isn't an authorization system in itself, but everyone and their dog has a "Login with..." option. And in order to do this it's necessary to use OAuth2 (or some form of API identifier). That's what I'm trying to do.
Does the following sound like the correct flow:
Get temporary code from auth server
Trade that for access token
Get user data from auth server and do whatever you want with it (probably save to a DB).
Log the user in, saving the refresh token as well.
Set an identifier in a cookie for the user (the access token)
When user comes back, identify them via the cookie token.
Try to make a call to the api and see if the access token is still valid.
If access token is still valid, great!
If access token isn't valid, then get a new one via the refresh token.
Is that the basic gist of using OAuth2 to help authenticate a user?
First of all, OAuth2 is not an authentication protocol. The issued access token does not sign you in, but allows you to call a web service (API).
OpenID Connect is an authentication protocol built on top of OAuth2. It allows you to get back an id_token from the authorization server that identifies the user. If you safe the token (or the info in it) in for example a cookie, you can establish a authenticated session for the user.
You also do not store access tokens in a database. Access tokens are short-lived and storing them on the server side serves no purpose.
You do store the refresh token in a database. When the client (app requesting the token) is confidential (can keep a secret), a refresh token may be issued. The client can use this refresh token to request a new access token for the API when the old token expires. This is what will surely happen when the user did not visit the app for a week.
This is what I do when using OAuth 2 tokens:
1.) You should store the access token in the local storage of your client. So once you stored it you can use it for every request you make like adding it to the Authorization Header "Bearer " + accessToken;
Don't forget to clear the local storage of your client when they logout.
2.) Basically if you send a request to the API and it returns "HTTP Error 401 Unauthorized" (Status 401) then you know that you should immediately re-direct the user to the login page because he/she is not authorized.
Well, if you are using role-based authorization then there's a possibility that the user is logged-in but is not authorized. This scenario should be handled by you. Only display actions on the UI corresponding to the authorization level of the user.
Hope this helps.

Authentication with my existing login system after Facebook Login?

I have a web application built using React that has an existing User/Session system. Right now, username and password are passed to server to authenticate and create session.
Enter Facebook Login (web). I want to allow for both username/password and also Facebook Login. So, now Facebook Dialog box appears and users can connect. I now receive the Facebook User Id and access token (short-life) on the client side (not the server side). How, now do I authenticate this user on my existing system and create a session?
If I use just the user id, this reveals a security issue (anyone can authenticate with a known user id and get a hijacked session). The short-lived access token is just that, short-lived. So that can't be used as an effective "password". So, what is the best way to securely authenticate someone on my existing login system if they've authenticated themselves via Facebook.
Thanks so much.
Found another user with the same issue here. It was resolved by the following:
The Facebook login request returns user id + short lived access token (client side).
Use the server side Facebook SDK to check the validity of the access token (will return user_id and app_id fields if valid).
You can trust the user_id field returned from the Facebook API to check against your existing user database.

oAuth 2.0 - Acting on behalf of the user

I'm new to oAUth2 and I'm trying to get a few things straight.
I understand the basic principles involved with oAuth2 but I am not sure how to implement it in my situation.
I am writing an app that acts on behalf of the user to automate a manual process and perform some tasks(update/request status...etc). The API we are connecting to uses oAuth2 to grant our application permission. We plan on having the user grant our application permission when they create a new account with us.
I understand that the user will request an authentication code that is provided to our application. Then our application will use the authentication code to generate an access token.
We would like to do this only once. Then act as the user to send and receive notifications without having to have the user to log into the service with their credentials.
I am not sure how to implement this without having to store the user credentials to get an auth code since the auth code and auth tokens expire. I'm guessing that this is a common scenario.
What would I need to do to get what I want accomplished?
You can get a new AccessToken using a RefreshToken, if this is provided by the Authorization Server.
If it's not provided I would contact the Api provider, you should never store a users credentials. In fact if the OAuth protocol is well implemented as a client you should never be able to even get the client credentials. When the user has to login you should redirect the user to the Authorization Server, there the user should login and then the authorization token should be redirected to your application by the Authorization Server.
See also this explanation on Refresh Tokens from the OAuth 2.0 spec:
Refresh tokens are credentials used to obtain access tokens. Refresh
tokens are issued to the client by the authorization server and are
used to obtain a new access token when the current access token
becomes invalid or expires, or to obtain additional access tokens
with identical or narrower scope (access tokens may have a shorter
lifetime and fewer permissions than authorized by the resource
owner). Issuing a refresh token is optional at the discretion of the
authorization server. If the authorization server issues a refresh
token, it is included when issuing an access token
Note
If you request a new AccessToken using your RefreshToken and the response includes a new RefreshToken you should overwrite your currently saved RefreshToken. With other words, you should always use the latest RefresthToken you received.