Keycloak optimization of requests - keycloak

I am using {server}/admin/realms/{realm}/users/{userId}/execute-actions-email endpoint.
The users are in separate database and I am using provider.
Before call this request I need call 3 requests.
1.{server}/realms/{realm}/protocol/openid-connect/token --access_token for user
2.{server}/realms/{realm}/protocol/openid-connect/userinfo --use acces_token from request 1., I get userId
3.{server}/realms/master/protocol/openid-connect/token --access_token for admin
4.{server}/admin/realms/{realm}/users/{userId}/execute-actions-email
where userid is from request2 and access_token from request 3. as ADMIN
How can I to solve it, pls?

Related

Keycloak returns Unauthorized 401

I'm running bitnami's Keycloak image on my local.
what I want to do is; use Keycloak REST APIs.
but no matter how hard I try, I'm getting 401.
I have done what's written in the doc. so this is a screenshot of the client. access type is confidential, and a service account is enabled. this is testapi client that I created;
here you can see the service account roles;
to view and manage users, I assigned manage-users and view-user roles.
firstly, to get the access_token , I'm using client_id and client_credential.
as you can see from here;
I have no problem getting the access token.
but when I try to get the user list or create a new user, I always get 401.
here you can see that I used the SAME access_token that I got from the http://localhost:8092/auth/realms/test/protocol/openid-connect/token
it doesn't make sense. I started to think about smashing the computer.
any help would be greatly appreciated
it doesnt work like this ,the process of getting users is as below:
First try to get access token for admin
POST http://localhost:8080/realms/master/protocol/openid-connect/token
the body of ur request will be x-wwww-url-encoded
client_id = admin-cli
username=admin
password=admin's password
grant_type=password
the response contains access token for admin
Second step is to get users of your realm in your case is test
Get http://localhost:8080/admin/realms/test/users
and pass the bearer token of admin in this request

Extract roles from REST API in Keycloak

At my company, we need to extract the roles of the logged in user from the REST API that Keycloak provides. We have looked through the Keycloak documentation but can't find the answers we are looking for. Let me explain the flow we want to implement: A user logs in to a client defined in Keycloak and receives a JWT which is stored in the applications web client. The user is not an admin in Keycloak. When the web client makes a request to the backend server, the backend server queries Keycloak for the user's roles. And, this is the point where we have trouble. We can't figure out the correct URL for the REST API or which token to add to the authentication header.
To summarize: we need help with the URL which is needed to query for user roles and what token to send to authorize against the API. I'm aware that the roles can be retrieved from the JWT, but we are afraid that the payload will become to big over time. A user may have multiple roles in different departments.
The roles should be in the JWT payload, this should be configured in the keycloak service. The flow should be something like this:
User is authenticated by the front end and the JWT token returned by keycloak is stored
The front end hits the back end including the token in the request header
The back end takes the token, validates it using the public key (the public key is provided by keycloak), if the token is valid, the roles are taken from the token payload and the authorization process is executed

How to prevent authenticated user from spoofing restful api calls

So I build a RESTful API. It has an /account/{id} endpoint to return user data. The API is secured via an identity server that issues the requester a JSON Web token (JWT) with access to the /account/{id} endpoint. The user sends a request with username and password and receives a JWT in return on successful authentication. Now the user sends a request for their account information to /account/{id}. The request is sent with a token in the header and returns a 200 response with the user data in the payload.
How would one go about authorizing the {id} in the endpoint? In other words, an authenticated user could just add any {id} in the endpoint and potentially receive another user's data. How is this prevented using the JWT?
You can store data in a web token. If you store the ID of the user, then you can identify them for each request they make. This is safe, because the contents of the token are signed with the private key of the server. Therefore their contents cannot be changed.
After that you can either limit the API so that each user can only query their own record, or you can also implement a complex role system, where each user has a set of roles (e.g. read-only, guest, maintainer, admin, client, etc.) that define which endpoints and how they can use.

AWS Cognito, Lambda, User credentials in DynamoDB

I established a authentication flow with Facebook Login and AWS Cognito on the client site. Works fine. But now I need a reference of the user with its facebook id in a dynambodb table. Of course I could just call a AWS lambda function exposed via AWS API gateway, but how can I verify that the API call actually has a valid facebook id and that this facebook id matches the AWS Cognito Id. Maybe I am missing something here, I hope you guys can point me in the right direction ;) thanks!
If you can key your ddb table by cognito id instead of facebook id, you can invoke api gateway with cognito credentials. If you use callee credentials when calling lambda you can access the cognito id via the token $context.identity.cognitoIdentityId. This ensures the call was made by the owner of this id. You can further check that $context.identity.cognitoAuthenticationProvider is graph.facebook.com to ensure they authed via Facebook. Unfortunately, the facebook id is not passed in the credentials, so if you need it you will need a lookup table mapping cognito id to facebook id. For more details on the available tokens see here.
I would suggest to do the following (I'm new to AWS as well, Let me know if you have any suggestions):
Create a API Gateway /fblogin endpoint where you will POST the Facebook Access Token (You will authenticate with Facebook on the client side to get this token). That endpoint is linked to a Lambda function say fb_login.
In fb_login function you will authenticate with Amazon Cognito to get its credentials. You should have created a Federated Identity user pool in Cognito and assign appropriate roles to assume for this user pool. This helps if you want to restrict your API only to those who are authenticated and authorized. So, the result from Cognito will have IdentityId and Credentials. You can return them as a result of your request to /fblogin.
Using the above result you can sign the requests you send to your API on API Gateway (Or you can use AWS custom generated SDK for your API to handle the signing). On the API Gateway endpoints, enable CORS and authentication as AWS_IAM. This way, API Gateway verifies the user automatically by checking the signature in the request. You can get the User Id from $context.identity.cognitoIdentityId as others suggested. This way, you can be sure that the user is authorized and authenticated.
Note: Make sure you implement /fblogin endpoint on HTTPS, then the FB Access token will be secure. If not, it will be visible as plain text over HTTP.
Also, use a Dynamo DB table as a log for CognitoID - FacebookID. You can incorporate this in the Step 2 Lambda function ifself or anything you think is appropriate.

Understanding OAuth2 flow

I'm developing an Android app that consumes a REST service that uses OAuth protocol. In the first activity, app shows a login screen. This is the flow:
1) User puts her username and password.
2) App makes a request to REST service, providing username and password.
3) REST service check the credentials and if are correct, ask for an access_token to my OAuth2 provider server.
4) REST service answers to the app providing the access_token and the refresh_token
5) In the next requests to the REST server (to get data like people, articles...) app will provide the access_token and the refresh_token.
6) When REST service process a request, will validate the access_token (using an token info endpoint of my OAuth server).
7) If the access_token is correct and has not expired, REST service will return the data that the app were asking for.
When REST service detects that access_token has expired, asks for another with using the refresh_roken.
Now, my questions:
When REST service retrieve a new access_token after the old one expires, has the REST service send it to the app in that response?
If so, has the app check, in each request/response, if new a new access_token has been sent from the REST service?
I don't know if I'm in the right way, I'm trying to understand the flow.
Thanks.
Assuming there's no browser involved and the app (aka. Client) uses what is called the Resource Owner Password Credentials grant, the flow is:
the User (aka. Resource Owner) provides his/her username and password to the Client
the Client makes a Token Request to the Authorization Server, providing username and password
the Authorization Server checks the credentials and if they are correct, it provides an access token and optionally a refresh token to the Client in the response
in the requests to the REST server (to get data like people, articles...) the Client will provide the access token
when the REST service process a request, it will validate the access token calling the token validation endpoint of the Authorization Server or by validating the token locally (e.g. if the access token is a JWT).
if the access token is correct, has not expired and has the right permissions (aka. "scopes"), the REST service will return the data that the Client was asking for
when the Client detects that access_token has expired (e.g. because the REST server returns an error), it asks the Authorization Server for another access token using the refresh token using the so-called Refresh Token grant/flow
OAuth 2.0 flows:
An application registers with the auth provider e.g. Facebook, Google, etc with app name, website and callback/postback URL
The application receives the client id and secret from the auth provider
The application user accesses the auth provider for authentication and user approves the resource permissions
The auth provider returns the auth token with respect to the user permissions to the application
The application accesses the resource provider using the auth tokens
The resource provider returns the protected resources after validating the auth tokens to the application
Do comment if you need more understanding!