The application is in Java.
application.yml
server:
port: 9000
platform.properties
jwt.secret="......."
jwt.expiration.time=864000000
jwt.header.prefix=Bearer
jwt.header=my_token
Controller
#PostMapping("/login")
public Result login(#RequestBody LoginRequestDto user){
return userService.login(user);
}
From Postman I'm trying to send a POST request to http://188.130.139.104:9000/login
On the Authorization tab, I select
Type: Basic Auth
I fill in the Username and Password fields
As a result , I get
Could not send request
This looks like you're using oauth2 access token. To replicate that on postman you have two options. The two options adds Authorization to the header of your request.
Option 1:
On the Authorization tab, scroll to Bearer Token. Then put in your token in the 'Token' input field.
Option 2:
You can add it to your headers directly via the Header tab
Related
I am using postman and I've tried updating a user's profile via http://localhost:8180/auth/admin/realms/demo/users/{userID} but I received a 401 response.
The procedure I used:
Requested and received admin token via http://localhost:8180/auth/realms/master/protocol/openid-connect/token
Added token to request headers the appropriate way i.e Authorization: Bearer {access_token}
Sent Put request with Json content type and the user's info as body via http://localhost:8180/auth/admin/realms/demo/users/{userID}.
Unfortunately, I've received back-to-back 401 responses.
First request:
-Body(x-www-form-urlencoded)
client_id : admin_cli
username: ...
password: ...
grant_type: password
client_secret: ...
-To http://localhost:8180/auth/realms/master/protocol/openid-connect/token
Second request:
-Header -> Authorization: Bearer ...
-Body(JSON)
"email": "d#gmail.com",
"firstName": "divad",
"lastName": "d"
-To http://localhost:8180/auth/admin/realms/demo/users/{userID}
In your first call, the david user has to be one with admin-alike privileges. Otherwise, one gets an authorized error response for the actions that the david user does not have the privileges to perform. Have a look at this SO thread to check how to assign admin-alike privileges to a user.
For now let us request a token on the behalf of the master admin user as follows:
from the body response extract the access_token.
For the second call first, copy and paste the access_token to the Authorization > Type Bearer Token:
On the second call, instead of
http://localhost:8180/auth/admin/realms/demo/users/{userID}
you need to replace the userID parameter with the actual userID of the user that you are updating. To get userID you can call the following endpoint:
GET <YOUR_KEYCLOAK_DOMAIN>/auth/admin/realms/<YOUR_REALM>/users/?username=<THE_USERNAME>
or you can copy and paste from the Keycloak Admin Console, under the tab users:
So in Postman would look like:
In my application, all I want to do is to get the user's Gmail. I don't use any google services. I want to add Google Sign In for Java front end and validate the user in Java backend.
I am following openid-connect document.
By opening the following link in the browser, I can get the code.
(GET) Request:
https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?
response_type=code&
scope=openid&
redirect_uri=http://localhost:3000/auth/&
client_id=113291176157....
/auth endpoint gets the following:
{
code: '4/0AfDhmrjDTOo7zOrXxm98E...',
scope: 'openid',
authuser: '0',
prompt: 'none'
}
Now to get user details,
(POST) Request:
https://oauth2.googleapis.com/token
{
"code": "4/0AfDhmrjDTOo7zOrXxm98E...",
"client_id": "113291176157-aibhsqjf655ve...",
"client_secret": "lLjenLdeaJnd...",
"redirect_uri": "http://localhost:3000/auth",
"grant_type": "authorization_code"
}
But I get the following response:
{
"error": "redirect_uri_mismatch",
"error_description": "Bad Request"
}
I have added the redirect URL to credentials:
Right now, I'm hoping to open a browser window from Java front end for the user to login to Google. I will receive the code value, and it will get id_token and validate the user.
I have seen some javascript examples, where they get the id_token directly.
So I have multiple questions,
Why do I need to get the code first and request id_token later?
Why am I getting redirect_uri_mismatch error?
Authorization code exchange request looks like below,
URL: https://oauth2.googleapis.com/token
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code
The request should be POST and data should be sent as urlencoded data, not in the request body.
More information about code exchange
This is my first encounter with a JWT token and I'd like to know how is this token returned to the client after it's first created.
Should it come in the Authorization : Bearer header ?
Usually, it's the client that passes the token in Authorization : Bearer header on each request.
I'd like to know how does the server pass this token to the client after user has authenticated and the token gets created. Also in the same header? In a different header?
In my situation, the server will be generating the token not as a response but as part of the request.
For example:-
A user will login to a portal, then click on a link to an authorized application. The JWT containing user claims will be passed to the authorized application as part of the request.
What is the best approach here? GET or POST? Header (which)? Query string? POST body?
Thank you!
there is no standard for how to return JWT token to the client, however, check this URL, it answers your question
https://github.com/dwyl/hapi-auth-jwt2/issues/82#issuecomment-129873082
putting the JWT token in the Authorization header gives us flexibility to send an actual response in a web application. For a REST-only App/API you are free to send the JWT as the response body or a cookie. What matters is how the client stores the JWT and sends it back to the Server, which is done in the Authorization header (or Cookie or URL Token if you prefer) 👍
As for this existing in the "wild", I have not seen an example of the server sending an Authorisation header to the client, but there is nothing in the spec to suggest this is an anti-pattern.
see: http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html
If you want to stick to the guidelines you would do follow this example: http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html#ExAccTokResp
One may be interested to know that the OAuth 2.0 standard specifies the response body for that purpose:
5.1. Successful Response
The authorization server issues an access token and optional refresh
token, and constructs the response by adding the following parameters
to the entity-body of the HTTP response with a 200 (OK) status code:
access_token
REQUIRED. The access token issued by the authorization server.
[...]
I need to make the user keep login in the system if the user's access_token get expired and user want to keep login. How can I get newly updated access_token with the use of refresh_token on Keycloak?
I am using vertx-auth for the auth implementation with Keycloak on vert.x. Is it possible to refresh access_token with vertx-auth or Keycloak's REST API itself? Or what will be another implementation of this?
keycloak has REST API for creating an access_token using refresh_token. It is a POST endpoint with application/x-www-form-urlencoded
Here is how it looks:
Method: POST
URL: https://keycloak.example.com/auth/realms/myrealm/protocol/openid-connect/token
Body type: x-www-form-urlencoded
Form fields:
client_id : <my-client-name>
grant_type : refresh_token
refresh_token: <my-refresh-token>
This will give you new access token using refresh token.
NOTE: if your refresh token is expired it will throw 400 exception in that you can make user login again.
Check out a sample in Postman, you can develop and corresponding API using this.
#maslick is correct you have to supply the client secret too, no need for authorization header in this case:
http://localhost:8080/auth/realms/{realm}/protocol/openid-connect/token
In case of expired refresh token it returns:
If you don't add the secret you get 401 unauthorized even though the refresh token is correct
I tried with 4.8.2.Final, it gives following unauthorized_client even with previous access token as 'Bearer'.
Then I tried with Basic YXBwLXByb3h5OnNlY3JldA== in Authorization header.
Then it worked, But still I'm not sure that I am doing right thing.
Extending Yogendra Mishra's answer. Note that
client_id and client_secret can also be sent in Authorization header.
Authorization: Basic ${Base64(<client_id>:<client_secret>)}
This works for both initial token call (without refresh token) and refresh token call to /openid-connect/token endpoint
Reference:
https://developer.okta.com/docs/reference/api/oidc/#client-secret
So after reading lots about BasicAuth, OAuth, JWT... etc. i came up with this question.
I have a client where some ppl can log in (Authentication is done). When ppl want to do an api call they use the clients GUI and the client is sending some requests to the a webservice endpoint.
host/resources/{id}
//id=path, res=post
public Response updateResourceById(String id, Resource res) {
....
So a typical update call could be
POST host/resources/1234 -d={ some json for a resource }
Now i don't want every user to have all rights for every reosurce, so i would
need to add some info about the user who is doing a request.
For this i was thinking to use some JSON Token with some payload (or any user info at all). But i was wondering how to send this token correctly in a RESTful API.
My first idea would be to change the code to something like this:
//id=path, token=post
public Response updateResourceById(String id, Token token) {
...
The endpoint would not change only the POST data.
Would this be correct or are there other approaches?
Edit: Also possible would be sending the Token via HTTP Header.
Sending credentials in HTTP
In HTTP, the credentials should be sent in the standard HTTP Authorization header.
Have a look at the RFC 7235, the current reference for authentication in HTTP 1.1:
4.2. Authorization
The Authorization header field allows a user agent to authenticate
itself with an origin server -- usually, but not necessarily, after
receiving a 401 (Unauthorized) response. Its value consists of
credentials containing the authentication information of the user
agent for the realm of the resource being requested.
Authorization = credentials
[...]
Please note that the name of this HTTP header is unfortunate because it carries authentication data instead of authorization. Anyways, this is the standard header for sending credentials.
In a token based authentication, the tokens are credentials. In this approach, hard credentials such as username and password are exchanged for a token that is sent in each request to identify a user.
It never hurts to say that you should use HTTPS when sending sensitive data, such as credentials, over the wire. HTTPS will protect your application against the man-in-the-middle attack.
Reading the authentication token in JAX-RS
You can read the Authorization header in a JAX-RS application as following and then check if the token is valid:
#GET
public Response myMethod(#HeaderParam("Authorization") String token) {
...
}
However, a better approach would be using a ContainerRequestFilter, keeping your endpoints leans and focused on the business logic. For more information on token based authentication and on how to use a ContainerRequestFilter, have a look at this question.