Is checking subsequent REST API request with token secure enough? - rest

In my REST API, user will log in with their username and password for the first time.
When they logged in successfully, we will response with the following format.
{
"token": "0c7f8b870675bc61d92baeef1e274c2d31343736393530373230",
"expire_on": "2016-11-19T18:05:20+0000",
"user_id": 30,
"user": {...}
}
On the subsequent to the REST API, we will just send token in the header to verify the user. token is 52 letters long.
Is it secure enough?
Should I send both token and user_id to verify to secure more?

It depends on how do you generate your token.
If someone can guess how they are generated then it can create a fake one.
If this is a random string that is saved on your server and for each request you check the existence in your server then you are safe.
The best current solution for stateless token is JWT. Take a look at https://jwt.io/

Did you implement your authentication layer? I would suggest having a look at the Oauth2 specification and you are interested in the section when the grant_type is password. If you follow it, it will be safe to return just the access token:
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.
token_type
REQUIRED. The type of the token issued as described in
Section 7.1. Value is case insensitive.
expires_in
RECOMMENDED. The lifetime in seconds of the access token. For
example, the value "3600" denotes that the access token will
expire in one hour from the time the response was generated.
If omitted, the authorization server SHOULD provide the
expiration time via other means or document the default value
.

Related

Authorization header does not have valid access token in paypal using rest api

sir,
i need help in this topic what i am doing is i try to get the transaction details using paymentid using https://api-m.sandbox.paypal.com/v1/oauth2/token this by passwing user name and password as argument in post man but unable to get the valid request it says that
{"error":"invalid_token","error_description":"Authorization header does not have valid access token"}
i there any way that i cam get the transaction history of a transaction available please guide me
is there any API call available there
The PayPal REST API does not use a username and password for authentication.
First, a client ID and secret are used to obtain an access_token which will be valid for up to 9 hours. These values an be passed as the "username" and "password" fields of HTTP Basic Authentication, if that is what you are referring to -- which means they will be concatenated with a colon separator and base64 encoded, then placed in the Authentication header after the word "Basic ".
Once an access_token is obtained from the oauth2 endpoint, it must be sent as a header for any actual API calls before expiring For details, see the documentation.
If you need a postman collection that already implements oauth token generation in pre-request scripts, see https://www.postman.com/paypal

How RESTful token authentication works

I understand that i have to provide a token to a client upon a successful authentication. What i still don't understand is how a server validates the token and its expiration time.
If RESTful services are stateless, how is it possible to authenticate a token on the server? Could anyone provide examples of token validation?
If RESTful services are stateless, how is it possible to authenticate a token on the server?
The server stores no state, the state used to validate a token is contained inside the token e.g. an expiration date & an account ID. A very simple, pseudo, example:
if token.expiry < now then
return tokenExpired
If !findUser(token.accountId) then
return accountNotFound
return tokenOk
The server may keep track of what tokens it has issued as a security measure to ensure old tokens can't be reused, and such that tokens can't be forged. So if we take the previous example it could updated to include an additional check
if !tokenActive(token) then
return tokenInvalid
the token contains some usefull information, like the date, some values like the username or email and others fields.
If I take for example the JWT token, you will find 3 'fields of information'
1/ header
2/ payload
3/ verify signature
You will find more datas on this website : https://jwt.io/introduction/

Process JWT token using JWKs Endpoint

I receive two JWTs: an OpenID Connect ID token (id_token) and an Access Token (access_token). The situation with OpenID is more or less clear - I can validate it using a JWKS Endpoint: https://smth.com/JWKS.
as in example (https://bitbucket.org/b_c/jose4j/wiki/JWT%20Examples):
HttpsJwks httpsJkws = new HttpsJwks("https://smth.com/JWKS");
HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
jwtConsumer = new JwtConsumerBuilder()
.setVerificationKeyResolver(httpsJwksKeyResolver)
.setExpectedAudience(...)
.setExpectedIssuer(...)
.build();
The question is how to proceed with the Access Token. I can extract from it the userId and userDetails, but I guess I need also to validate it?
If I try to validate the Access Token the same as for the ID Token, I am getting this error:
UnresolvableKeyException: Unable to find a suitable verification key for JWS w/ header {"alg" : "RS256", "kid":"1"}
And indeed there is no key for "kid" : "1", Also this value "1" seems kind of strange?
Am I doing something totally wrong?
It sounds like you are implementing the role of OpenID Connect client or Relying Party. The two tokens, ID token and access token, serve different purposes and should be handled differently by the client. The ID token is intended for the client and enables authentication of the end-user at the client. The client must validate the ID token (verify the signature and validate claims like exp and aud, etc.) before allowing the end-user in. The access token, however, is for the client to use to access resources or APIs but is not directly intended for the client to consume or validate. The access token is opaque to the client and the client shouldn't care or know about its details. In fact, access tokens aren't always JWTs. In OpenID Connect, the access token is used to call the user info endpoint (with the HTTP header, Authorization: Bearer [access token]) to get more claims/info about the end-user.
The value of "1" for the kid is totally legal but it is referring to a key that the AS/OP and the user info endpoint know about somehow. It is not a key at the OpenID Connect JWKS endpoint. "1" isn't a key that the client needs to know about because the client isn't supposed to directly verify the access token.

How to Validate JWT Token issued by Thinktecture identity server?

Is there any way that when the OAuth client get the JWT token from identity server is OK or not?
I afraid the when user get the access_token and try to use base64 to decode it then users can modify the token string .
My scenario is :
I have two web portal A and B both of them integrated the Thinktecture identity server.
User A just can access portal A with "role:portalA" claim but couldn't access portal B
if user A try to login portal A and get the access_token then user A add the "role:portalB" into the the access_token then encode with base64 again.
then the modified access_token pass to the Portal B, I afraid that user A could access portal B. so I have to check the access_token to Identity server again. is that any way to validate this access_token ? or this situation will not be happened?
I believe Thinktecture Identity Server has an endpoint for this at (baseurl + "/core/accessTokenValidation?token=" + access_token).
example:
GET request to: http://localhost:3333/core/accessTokenValidation?token=aEdhoi23hlv2khdf2lkhfv4pv....
If the access_token is valid, it should return a 200 response, otherwise it'll return a JSON error message {"error":"invalid_token"} and a 4XX response.
You should wire up a call to this service to validate tokens, then cache the response.
Take a look at the source code: https://github.com/IdentityServer/IdentityServer3/blob/master/source/Core/Endpoints/Connect/AccessTokenValidationController.cs
Thinktecture IdentityServer3 has different endpoint.
More details in official documentation:
https://identityserver.github.io/Documentation/docs/endpoints/accessTokenValidation.html
Example:
GET /connect/accesstokenvalidation?token=<token>
A successful response will return a status code of 200 and the associated claims for the token.
An unsuccessful response will return a 400 with an error message.

RESTful authentication scheme

I need to implement an authentication scheme for a RESTful architecture. From several articles which I have read include basic Authentication using HTTPs and Session management using Cookie.
However I'm not well understanding the use of cookie. What i understands is that user first sends credentials. The server checks if the credentials are Ok. If yes, the server generates an authorization token and place it in the cookie. Onwards, on each and every request, server checks the validity of the token in the cookie.
But how does the server know that the content of the cookie is valid. Does it stores it somewhere and then it compares it??
The key point here is the authorization token. When generating one and sending back to the client, you store the auth token along with the username in let's say a database. You store the auth token in the cookie. The client on subsequent requests sends you the username and the cookie alongwith which contains the auth token. You verify this token against the supplied username and then perform the action per need.
However, do note that settings cookies makes your webservice call stateful and defeats the purpose of REST.
To achieve authentication/authorization, instead of setting the authorization token in the cookie, send it back as a response value. The client reads the value of auth token and then supplies the same in every REST request as a parameter of request body. Thus, you won't need to set cookies. This you may term as the toned down and simpler version of what is implemented in OAuth based API access.
I'm not an expert, but a good starting point to understand this is the section on Sessions in Hartl's book.
If I'm not mistaken it works as follows:
When the token is created, it uses a formula, e.g. the username and a unique user key (a salt) encrypted together. Both the username and the salt are stored in the database, and the salt is unique to that user. So, as you would do to compare if passwords match, to check the validity of the cookie you recreate the token and compare it to the one in the cookie. If it matches, then the right user is logged in and therefore authorised.
Hope this helps, or at least points you in the right direction :)