We are trying to set up a scheduled job based on NodeJS which will call an API via an API gateway. The API calls another API. There is no user or browser involved. The call must be authenticated and have a valid OAuth token from our IdP. How should it look like to have a more secure approach?
How the flow should look like? Which one the API Gateway or the second API should validate the token? or both? Thanks
A key point is that JWT access token validation is designed to scale. In older architectures it was common to use perimeter security (eg API gateway validates token) but this is no longer recommended.
Instead validate the JWT in each API using a library. Here is some example code and for other technologies see Curity API Guides.
Here are a couple of related articles if you are interested in API security trends:
Zero Trust Architecture
Phantom Token Pattern
Finally, this article discusses that JWTs can often be forwarded between microservices, to keep your code simple.
Related
The IANA registry of Authentication schemes (http://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml) states that the Bearer authentication scheme is defined in the context of the Oauth protocol.
Does it make sense using a bearer token without an OAuth setting?
For example: I want to call an API of another company; we agree on a custom scheme for a JWT security token to add to an API call (for example, suppose you don't use an Authorization Server as OAUTH would require, we use another custom mechanism). The JWT is signed and encoded and added to an API call using the Authorization http header with a bearer authentication scheme.
The question is not if this can work, because I know it can and it is good enough from a security point of view (this is why I don't add much details about the real implementation).
My question is about use of the standards: from a formal point of view are we right if we declare a bearer token outside of an Oauth setting?
A second question could be: would it be possible to declare a custom authentication scheme, for example 'myBearer'?
Thank You,
Corrado Tamietti
I would recommend following a standard pattern for your B2B security. Usually this involves an Authorization Server, but if there isn't one, for reasons out of your control, then using tokens can still be useful, in order to:
Communicate scopes to represent areas of data
Communicate claims used for finer grained authorization rules
I would design a solution around the following rules:
Company B, who own the API, must issue the access tokens. Only they should have access to the private key used to issue them. They can then control privileges, time to live and other aspects.
Company A have to call a Company B endpoint to get an access token, which involves sending a credential. The token received should be fairly confidential and not contain sensitive data.
Company A then sends that access token to other Company B endpoints to access data.
Even if you keep OAuth behaviour light for the time being, this is a standard pattern that should fit nicely into your applications and support future extensibility.
USE OF AUTHORIZATION HEADER
The link you provided referenced OAuth 1.0, which used the OAUTH keyword
in the Authorization header - but very few people use OAuth v1 these days, partly because it is less web / mobile friendly than OAuth v2.
OAuth v2 best practice involves sending JWTs via the general HTTP mechanism of the Authorization header - see this section from the draft OAuth 2.1 spec.
If you are using standard JWTs (without more advanced features such as proof of possession) then using 'bearer' feels like the right option to me. This describes only how the API message credential is presented and does not have to mean that a full OAuth solution is in place.
FURTHER DETAILS ON AUTHORIZATION AND B2B
OAuth B2B APIs usually use the Client Credentials Grant, and if data sensitivity is high, step 2 often involves use of Mutual TLS. Here are some related links from the Curity Web Site:
Scopes in APIs
Claims in APIs
Financial Grade B2B APIs
I would like to implement quotas for users accessing my API but I'm not sure the flow I have in mind is the way to do by simply reading documentation from several API management solutions.
Currently, my flow could be described as follows :
The user provides credentials to the app
The app calls my Authorization Server for validation. The token is returned to the user if successful.
In the following requests, the app will validate the token (Authorization header) against the Authorization Server before accessing the service.
My problem is that I cannot implement quotas based on tokens since my users would be able to get a new token to avoid the limit. According to your experience, is it possible to manage quota by users at the gateway level or should I change my API authentication method?
Best regards,
When we speak of api and token the most used model of communication is the protocol OAuth 2.0.
Through it, API users must authenticate to their respective OAuth authentication server (it could be a third-party server, eg facebook or google).
With the token in hand and this token is a token with a limited lifetime, the exposed API must validate this token against the OAuth resource server which will identify who will be the client / application that is requesting.
Therefore, using OAuth token it will be possible to identify the requester.
Regarding quota control if you will not use any API Management / Gateway market player (Ex: apigee) you must implement this control with a high-performance query engine. For a simpler solution a key value pair database could solve this problem (eg redis).
I am struggling with understanding how to implement the following in Web API 2's OWIN pipeline.
I am building an application that will allow users to log in with several third-party identity providers such as Facebook, Twitter, LinkedIn, etc. However, I want the authentication step to be performed entirely client-side. For example, Facebook provides developers a snippet of markup and JavaScript that perform the authentication within the browser, resulting in a Facebook access token--all without any calls to my API.
The Web API templates that ship with Visual Studio 2013 all seem to assume that the API itself is in charge of the authentication flow. I have successfully gotten this style of authentication working, but in my opinion it is not the responsibility of the API to perform this work.
Here is the approach I have been trying to implement (so far unsuccessfully):
Provide endpoints like /authenticate/facebook that accept the appropriate access token and return a JWT with "decoded" claims if the access token is valid. This JWT would have similar claims regardless of the third-party identity provider. For Facebook, I think this involves a call to Graph API's /me endpoint.
Store the JWT in the browser's localStorage for subsequent API calls
Send the JWT in the Authorize header for each API call
Avoid cookies if at all possible
My questions:
Is this an appropriate way to handle third-party authorization?
Should the JWT's expiration match the third-party access token's? I assume yes, but I want to be aware of any caveats here.
Where and how do I store the third-party access tokens for use on subsequent API calls? Do I include them with the JWT?
Is there a template I can use out-of-the-box, or perhaps an online resource that implements authentication and authorization in this way? I don't understand how to use Web API's many classes and features to implement this.
I have this mostly figured out now. I believe my architecture choice is the correct one after much research, specifically into the so-called "assertion flow." I am using Thinktecture's Identity Server 3 project to act as my STS. I am using a custom implementation of ICustomGrantValidator to perform the validation of the Facebook access token and conversion to claims.
I would like to develop RESTful API for my web application. Client have to be clear JS + HTML and user have to somehow authenticate in system. I've read few articles about security and RESTful API but some point still are not clear for me. As I've understood at the first step user have to provide his credentials to server. After that server have to validate user credentials and if they are valid, sent some encoded token to user (assume it will be [user key]:[user IP]:[token creation time]). After user authentication client have to sent this this key with each API call. That's how I've understood RESTful API authentication principes.
With such solution I assume that token can be stolen and another user can access to secured user data (even if IP is included to access token and there will be validation on each request). For this purpose I plan to include token creation time but as I understand with such solution I have to renew access token each time when it expiring - in this case it's not clear for me how to implement "remember me" functionality.
It's not clear for me how to implement 100% safe authentication for my RESTful API. Maybe I'm missing something. Or maybe my understanding of authentication principes is wrong.
It depends from what authentication scenario you are using. For example when dealing with in ASP.NET MVC + REST with Basic Authentication it will produce for you token which is in the fact Base64 encoded string '{username}:{password}'. And you are right it could be stolen, that's why for Basic Auth HTTPS is must, as token goes throw Authentication header with Basic schema.
For REST security most suitable and secure are OpenId and OAuth. Just don't reinvent wheel and use already existing standards. OAuth in compare to OpenID includes not only authentication but authorization as well. OAuth already describes all nuances with token renew and token creation time and so on.
Now practical how to implement OAuth in REST. First of all read standard. For your case read with attention Implicit Grant flow, because standard has multiple flows for different client with different trust level and security.
https://www.rfc-editor.org/rfc/rfc6749
And after that you can try some already implemented library in technological stack you are using either Java or .NET. For client it is not so important to use library in compare but for server implementation
About potential security problem read here https://www.rfc-editor.org/rfc/rfc6749#section-10.
Some think that OAuth 2.0 is less secure that OAuth 1.0, and it is also dependant from token format. Anyway access token should be passed in HTTP Header and through HTTPS as well as clientid should be stored and passed securely.
I'm building Pylons-based web application with RESTful API, which currently lacks any authentication. So I'm going to implement that and in order to avoid all the trouble and caution with storing user passwords, I'd like to use OpenID for authentication. What would be the best way to do this? Are these two things compatible? Are there existing REST APIs that use OpenID that I can take inspiration from?
I've now spent some time researching the options and would like to summarize the findings.
First, a little bit more context -- I develop and control both the service and API consumer. Consumer is Flash-based app that is served from the same host the API is now and is supposed to be used in browser. No third party clients in sight yet.
So the question can be divided in two parts,
how do I do the OpenID authentication via API
how do I maintain the "authenticated" state in subsequent requests
For first part, OpenID authentication almost always includes interactive steps. During the authentication process there will most likely be a step where user is in OpenID provider's web page, signing in and pressing some "I agree" button. So API cannot and shouldn't handle this transparently (no "tell me your OpenID provider and password and I'll do the rest"). Best it can do is pass forth and back HTTP links that client has to open and follow instructions.
Maintaining "authenticated" state
REST APIs should be stateless, each request should include all the information needed to handle it, right? It wouldn't make any sense to authenticate against OpenID provider for each request, so some kind of session is neccessary. Some of the options for communicating session key (or "access token" or username/password) are:
HTTPS + BASIC authentication ("Authorization: Basic ..." header in each request)
Signing requests Amazon-style ("Authorization: AWS ... " header in each request)
OAuth: acquire Access Token, include that and a bunch of other parameters in each request
Cookie that stores session key ("Cookie: ... " header in each request)
Signed cookie that stores session information in the cookie itself
There's just one API consumer right now, so I chose to go for simplest thing that could possibly work -- cookies. They are super-easy to use in Pylons, with help of Beaker. They also "just work" in the Flash app -- since it runs inside browser, browser will include relevant cookies in the requests that Flash app makes -- the app doesn't need to be changed at all with respect to that. Here's one StackOverflow question that also advocates using cookies: RESTful authentication for web applications
Beaker also has nice feature of cookie-only sessions where all session data is contained in the cookie itself. I guess this is about as stateless as it gets. There is no session store on server. Cookies are signed and optionally encrypted to avoid tampering with them in client side. The drawback is that cookie gets a bit bigger, since it now needs to store more than just session key. By removing some stuff I didn't really need in the session (leftovers from OpenID authentication) I got the cookie size down to about 200 bytes.
OAuth is a better fit for API usage. Here's an example of OAuth in use in Python: oauth-python-twitter. Leah Culver's python-oauth library is the canonical implementation of OAuth in Python, but python-oauth2 is a recent contender that is getting some buzz. As for inspiration, django-piston has support for using OAuth to do auth when creating RESTful APIs for Django, though the documentation isn't as nice as I'd like for that particular topic.
If you build API, you could check OAuth protocol. It's complementary to OpenID.