How to setting JWT Authentication in KONGA - api-gateway

I want to add a JWT Authentication to my services.
I have done the following steps, but JWT Authentication is not working
Create a Consumer
Insert a JWT secret into Consumer
Add a JWT plugin with the Consumer id in Service and Route
However, the message that I get from Postman is Unauthorized.
I have no issue if I am using Key-Auth and Basic Auth. Too many website that I have seek and find, but not solve my problem.
I using jwt.io website to generate Token, but I am not sure the information to be fill in the Payload section.
JWT in Service/Route
JWT in Consumer
JWT in Website jwt.io (This is the confusing part, stuck here at Payload)
Postman
Appreciate if anyone can help me out.
KONGA version: 0.14.3
Kong version: 1.3.0

Same issue with you, every steps that you did were absolute correct. I also cannot find out the solution somewhere else. But luckily I got the solution after reviewing again all params to enable JWT plugin & create JWT for consumers.
I found this param config.header_names must be inputted as Authorization (remember type Enter after inputting :D).
Although the Kong document (https://docs.konghq.com/hub/kong-inc/jwt/) said that this value is optional and default value is "Authorization" but actually if you left it blank I realized that Kong cannot extract JWT from header.

The key claim name (in your case "iss") must exist in your jwt token and the consumer in kong must be configured to expect that (in "key" field for the respective consumer)
For the token to be valid, the value of "iss" in your token must be equal to the value of "key" that you entered while creating the consumer

Related

Google Oauth2 Bearer token as session id

I have implemented google-signin using the oauth2 from Angular Application.
Once authentication is successful and the token is generated, I am storing it in the LocalStorage/IndexedDB and also trying to send this Token, UserProfile info etc, to my flask-backend.
I would validate the token and continue the flow
Now, I want to use the user bearer token as my Session-ID, i.e, each API call I am doing, I will be doing by validating against this bearer token.
I believe by doing so, I will be able to avoid 'creating sessions' and also leverage the google-generated tokens for uniquely identifying users and the calls to backend.
Please let me know what security flaws this would give rise to and also what are the alternatives for the same
Although at the point of time I was making the question, it was a bit unclear on how to proceed, heres a summary of what I have accomplished -
1 - I have used Angular for frontend and I have refered this page
2 - While doing so, my doubt was how would I proceed with user authentication and how I would continue to register the user and get the required details like profile, contact, address etc.
What I have done ->
Once a bearer was issued, I was passing this info to backend and then, from the backend, I was reaching out to various google api's and getting relevant info with the bearer.
Also this bearer was being stored on client end so as to ensure UNTIL the token expires, I would continue to not issue another token and meanwhile, as and when the user session times out, I would read the locally stored(client side) token and validate it on backend,
should the token be valid, backend server would go and all the info for all the scopes, and deal the other flows accordingly.

django-rest-auth token authentication on client side

I have implemented Token Authentication in my api. When I send a POST request with user credentials, I get back the token. But I can't seem to figure how to implement client side logic to use this token. I mean do I store it somewhere?
From Django Rest Framework Docs
For clients to authenticate, the token key should be included in the Authorization HTTP header. The key should be prefixed by the string literal "Token", with whitespace separating the two strings. For example:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b1
So indeed, you need to store somewhere on the front-end.
You can read more about where is best place to store tokens here and here.

Oauth2 hash token on Auth Server

I'm implementing an Auth server using Spring Security Oauth2. What I noticed is that when spring security saves the access token (using JdbcTokenStore) , the OAuth2AccessToken is serialized as which means the access token is self is saved as plain text. I have a couple questions about this.
1.) The token is never actually retrieved using the access token value. It is retrieved using a token id. Why is that?
2.) Is it Ok to hash this token since it is never retrieved using it's value?
3.) Do we actually need to generate the token id? Can we pass an extra information from the resource server to the authentication server to retrieve the token and validate it against the hash?
By default Spring stores the token in plain text. If you make a request to get a token again in the same browser, you will notice that Spring will return the same token as long as it is still valid.
1) This is not entirely correct. On the resource server, the token is read from the header and a PreAuthenticatedAuthenticationToken is created. Through several steps the token value is used to create the OAuth2Authentication. The key is a intermediate step, but only after you have resolved the token to an OAuth2AccessToken (see TokenStore.readAccessToken())
2) Personally I would hash the token before storing it in the database! This does however require you to implement/extend a TokenStore, since you need to override TokenStore.storeAccessToken() to save the hashed value, and TokenStore.readAccessToken() to hash the incoming token and find the hash in the database.
3) Typically the authentication server and resource server read the same database, and both ends up with a OAuth2Authentication identifying the user. If you want to hash, you just need to implement the store/read methods as described above.
I have implemented a solution like this with Spring Oauth2 1½ ago, so hashing tokens and refresh tokens is diffidently possible. In our case we ended up not using the resource server implementation from Spring Oauth2, because we get 20K requests every minute, and we wanted to delay resolving the token until the request has been validated, and use several layers of caching to avoid hitting the database on every request.

Where does Web API store generated tokens in order to validate subsequent requests?

I have a Web API and AngularJS client. The API is using default authorization provider given by visual studio to generate the token on token request with grant_type 'password'.
The AngularJS client is able to get the bearer token from Web API by calling the token endpoint with credentials and later passes this token to perform authorized requests in the API.
When AngularJS sends the token on any authorized API call, how is Web API able to validate the token? Where does the token get stored?
I checked in Identity tables in SQL server, I could not find any fields to store this token information. I checked in the configuration file, it is not stored there either. Could you please help me in understanding this concept?
Raj,
By default the token is not stored by the server. Only your client has it and is sending it through the authorization header to the server.
If you used the default template provided by Visual Studio, in the Startup ConfigureAuth method the following IAppBuilder extension is called: app.UseOAuthBearerTokens(OAuthOptions).
This extension coming from the Microsoft.AspNet.Identity.Owin package makes it easy for you to generate and consume tokens, but it is confusing as it is an all in one.
Behind the scene it's using two Owin middlewares:
OAuthAuthorizationServerMiddleware: authorize and deliver tokens
OAuthBearerAuthenticationMiddleware: occurs at the PipelineStage.Authenticate, read the authorization header, check if the token is valid and authenticate the user.
To answer you questions WebAPI is able to validate the token thanks to the OAuthBearerAuthenticationMiddleware, it will ensure that the token sent through the authorization header is valid and not expired. And the token is stored only by your client, if the client loose it, it will have to request a new one.
I advise you to get deeper in the OAuth protocol, and instead of using the extension UseOAuthBearerTokens, take a look at UseOAuthAuthorizationServer and UseOAuthBearerAuthentication, it will help you to better understand how it works.
The generated token will most likely be a JWT (Get Started with JSON Web Tokens), which means it's a self-contained token that is signed with a secret/key that only the server or other trusted parties know.
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.
(emphasis is mine)
This means that when receiving the token the server can ensure that:
the token was originally issued by a trusted party by checking that the signature is valid.
the token is associated with a user that has permissions to perform the following request because the token itself contains information that uniquely identifier that user.
This type of approach has the side-benefit that the server does not need to keep track or store the generated tokens in order to validate them at a later time. Since no one else has the secret/key you can't modify the token without making the signature component invalid, which would then mean a faked token would end up being rejected by the server.
This is a simplified description of what happens, there are much more details around how to issue and validate tokens correctly. You should read the OAuth2 and OpenID Connect specification to learn more on the subject of token-based authentication.
Also note that I assumed a JWT token because it's the format that currently has the most widespread adoption to accomplish scenarios like these ones and it's also the token format to use in conjunction with OAuth2 and OpenID Connect. However, it's still possible to achieve the same with other token formats.

Laravel: API with OAuth 2.0

I am currently developing an API that I plan to secure using oauth2.
I have chosen: https://github.com/lucadegasperi/oauth2-server-laravel/
I have managed to secure the endpoint (using before=>oauth in my api routes) by following the installation guide but I am at a loss as to how am I gonna be able to authenticate and access the endpoint.
I do understand that you will first need to request an access_token by sending a client_id and client_secret but what I don't get is where do I set those on the oauth server?
I see the oauth controller has endpoints for these like:
http://somedomain.com/oauth/authorize
http://somedomain.com/oauth/access_token
But I am clueless with what to do with them. I only managed to arrive at the conclusion that it needs a client_id, client_secret, and stuff about scopes.
Where can I set these values for the api client to use?
Thank you for your help in advance.
I don't know Laravel, but in general, the authorization endpoint (in your case, http://somedomain.com/oauth/authorize) behaves as described in RFC 6749.
The specification defines four flows. If you use Authorization Code Flow among the flows, you should access the authorization endpoint with the following request parameters.
response_type=code (required)
client_id={your-client-id} (required)
scope={space-delimited-scope-names} (optional)
redirect_uri={your-redirect-uri} (conditionally optional)
state={any-arbitrary-string} (optional)
For example,
http://somedomain.com/oauth/authorize?response_type=code&client_id=your-client-id&scope=profile+email
The authorization endpoint generates an authorization code and returns it to your browser.
The next step is to access the token endpoint (in your case, http://somedomain.com/oauth/access_token) with the authorization code which has been issued from the authorization endpoint. Like this,
POST
http://somedomain.com/oauth/access_token?grant_type=authorization_code&code=issued-authorization-code&client_id=your-client-id&client_secret=your-client-secret
Anyway, I recommend you read RFC 6749.

Resources