I have Oauth2 implemented in my application to protect API calls.
My Oauth and resource server are on two separate physical boxes(but on same network). For each call on resource server it needs to call Oauth server for Oauthtoken validation.
I have millions of request coming to my resource server in a day.
Currently to validate Oauth token I am using rest call from resource Server to Oauth Server.
Is there a way to make this faster as each and every call needs to be redirected to Oauth server? Can webSockets solve this problem?
If you don't need to revoke individual access tokens, you can use stateless (JSON Web Token) JWT tokens. JWTs don't need to be validated on the authorization server. As long as the JWT token is signed by the authorization server (asymmetric cryptography), you can validate the token on the resource server itself using the authorization server's public key.
This makes for fast authorization (since it skips a server-to-server round trip) at the cost of easy revocability.
Note: you can also use a shared secret (symmetric cryptography) but then you need to make sure all the interested parties have the shared secret (and keep it secret).
Look into spring-security-jwt and https://jwt.io/
Related
I'm building a REST API using Elixir's Phoenix framework. In the API, I need to authenticate the user by phone number i.e., via sending an SMS OTP code. After authenticating the user, the Auth server sends the Access token and Refresh token to the client. The client(mobile app) stores those tokens locally and sends the Access token in the HTTP header as Authorization: Bearer <Access_Token> in every request to resource server. My actual question is, how do resource server validates the Access token that is received from the mobile app/client?
Does resource server needs to contact Auth server to validate the Access Token? That would a lot of overhead. Please help me understand RestFull API Authentication.
Thanks for taking the time to read my question.
It sounds like you have everything working up to validating the token. You are going to need the public key for the server that signed the token. It depends on what auth server you're working with on how you get that. In some cases you may be able to preload this key as a configuration setting on your backend. Otherwise you can probably get it via https request to the auth server. Most auth servers these days I expect to provide a JWKS api that you can use to get the keys you need. Then with the token and the public key you can use your elixir jwt library to validate that the token you have was signed by the server you trust, meaning the SMS code was validated, and you can proceed with whatever is needed in the backend to handle the request.
If you're using Joken for elixir you can review https://hexdocs.pm/joken_jwks/introduction.html and https://hexdocs.pm/joken/introduction.html for more information.
how do resource server validates the Access token that is received from the mobile app/client?
The same way a nightclub bouncer verifies your driving license as proof-of-age to let you in: by validating the authority and signatures, but it does not need to phone-up your DMV to verify that your license is real because it trusts the signatures (in this case, cryptographic signatures).
That said, some systems do use "reference tokens" which are short (say 32 bytes) of meaningless random data which are used as an unpredictable record identifier for some user-permissions record held by the authorization server. The resource-server will need to contact the auth server initially, but then it can simply cache the auth result itself for some time window.
Consider I'm creating a RESTful API (like Twitter API) and I need only a single key token to access the endpoint GET /messages.
The token needs to be sent via header access_token for example.
If I don't pass the token I'll get an 4xx error.
In the RESTful API scenario, is this all needed to protect against CSRF attacks? I mean, in RESTful APIs I'm not using Cookies to manager a user session, since the idea here is to not be a session (Stateless is one of the principles of REST).
Am I forgetting something or is this correct? I don't see why I would need a anti CSRF token besides my access token.
Thanks in advance!
Short answer: if your access_token is not a cookie, yes, it's enough to protect you against CSRF.
Long answer:
A CSRF attack can only happen when HTTP client automatically sends some authentication data(usually cookies) to server. The key point is attacker do not need to know the Cookie, it's is automatically sent if web user accesses 2 sites(your site and the attacker's site) using the same browser.
To anti CSRF, server sends to client a private token that browser does not automatically send it to server(so it's must not be a cookie). The developer has to write code to attach the token to each subsequent request.
CSRF is an issue for using Cookie by Web browser, if you are developing restful API that is not used by web browser, usually, you do not need to care about CSRF
#Bart Firstly CSRF attacks are usually from a trusted user. Which means that the client has successfully authenticated himself by maybe passing a valid token in case of a rest API. The attack could be by passing let's say a javascript which can change the state of a resource. So just having a single key token won't really help to avoid CSRF attacks.
Please refer to below URL for more reference on CSRF :-
https://en.wikipedia.org/wiki/Cross-site_request_forgery
Most of the frameworks like Spring have inbuilt support for CSRF.
I want to use the "microservice architecture" https://www.jhipster.tech/api-gateway/ using:
my company OpenID connect provider to authenticate users from the frontend SPA
JWT for authorization (that is, JWT from the moment the user is authenticated)
I'm not sure how that's supposed to be configured, or even if it's possible at all...
There are many architectural decisions you have to take on designing full system. But if you are going to use OpenID Conenct then there are few common aspects.
First, as you have figured out you must have a OpenID Connect provider (IDP). You have several options. You may use your own IDP for this purpose. Or else your micro-services may be controlled by an API gateway (Looking at Hipster architecture it does have one) which have a built in IDP for this. Regardless, from your application endpoint, you must use id token to authenticate the end user.
Now going into micro-service consumption, I see two options you can use. If your api gateway builds security for all micro services, then gateway must do the authorization part based on access tokens. But if you are consuming micro-services directly (without interaction with a gateway) then each micro-service handle authorization individually. Both have pros and cons but it's up to you to investigate and decide.
To sum up, your SPA consume id token for end user authentication. Once authenticated, you consume micro-services using the access token (preferably a JWT as you say). Once a micro-service receive a request, it will authorise the request based on access token JWT. For this one must validate JWT claims, signature of it as well as can use token introspection against IDP which issued the token.
We are looking into integrating keycloak to protect a front end AngularJS application which is served by a nodeJS application and also makes API requests to this server.
Having watched some tutorials, we see we need to use the javascript adapter for the AngularJS app to handle the user auth flow, and then protect our nodeJS application using the bearer only strategy, ensuring angularJS outgoing requests to our Node application contains an Auth header with the bearer token value present.
I have a question\concern about the way in which the token is being served back to the client as I can see it gets saved into a cookie which I assume is what the javascript adapter reads from in order for us to be able to write the Auth header into subsequent requests from the angular app.
My question is can this token value be easily read from the browser cookie and used maliciously by an attacker trying to make api requests?
Am I right in thinking it would be highly unlikely since the attacker would need to know the secret which is stored on the nodeJS side?
You don't need to know the client secret to use access token. That secret is used only to issue access token. If someone has your unexpired access token, then that someone will be able to use your identity until token expires. But you can minimise the possibility of the stolen access token by using https, httponly cookies. Also, you can use a short token lifetime (for example 5 minute). But then you will need to implement refresh tokens; otherwise, the user will need to re-login whenever access token expires.
I think the proper implementation is not trivial. I recommend using of some reverse auth-proxy, which will handle authorization and authentification in front of your app. Tip: https://github.com/gambol99/keycloak-proxy
I'm struggling with setting up reliable and performant solution to communicate frontend with different microservices. I do not really now how to maintain (maybe not need) CSRF between my frontend and end services
Solutions stack: PHP, Laravel Passport, JWT, oAuth 2.0, Axios
Current approach:
Actually I've started up with approach from Laravel's passport
https://laravel.com/docs/5.4/passport#consuming-your-api-with-javascript
Using oAuth 2.0 to authorize user from website A to service B.
JWT token is returned for further communication.
Token is saved in cookie within website A
Once user is authorized website A uses JWT token to manage requests without additional to oAuth server, by sending JWT token as cookie using HTTP headers (withCredentials) to authorize user.
For each website A's request there was CSRF token created from service B since user is authorized and cookie could be applied by another unauthorized website to access service B. That was killing my performance since it has to retrieve CSRF for each request made. (that what I actually assume from laravel passport approach and need to create CSRF with JWT token - maybe that was mistake)
My concerns:
Regarding to of James Ward post:
http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
The easiest way to do authentication without risking CSRF
vulnerabilities is to simply avoid using cookies to identify the user.
Cookies themselves are not the cause of CSRF vulnerabilities. It’s
using the cookies on the server to validate a user that is the cause
of CSRF. Just putting an authentication token into a cookie doesn’t
mean it must be used as the mechanism to identify the user.
From my understanding setting JWT with website A's cookie with its domain set could not be accessed via any other site from outside. Since that there is no possible way to make request to service B without accessing JWT.
So do we really need CSRF then to secure potential attack to service B while using JWT?
If so, how could I achieve the best (in term of performant) way to generate CSRF through different services to be sure that communication would not be vulnerable for attack from different sites?
Any advice will be appreciated!