I figured this has been answered before, but a quick SO search didn't yield anything.
I have a private API that is locked down by an APIKey. This key needs to be passed for each request. With this key you can access any part of the API. Obviously that's pretty open. For the most part this is acceptable. However, there are cases where I want to ensure that the request is sent by the owner of the data.
For example, consider an update or delete request. You shouldn't be able to make this request for someone else's data. So in addition to the APIKey, I'd like to have something else to ensure that this user making the request is authorized to perform that action.
I could require that an ownerID be passed with such request. But that's quickly forged. So what have I gained.
I am interested to hear what other members of SO have implemented in these situations. Individual APIKeys? Dual-authorization?
If it matters, my API follows the REST architecture and is developed with PHP/Apache.
API keys should be unique per user. This will verify the user and that they should have access to the data.
If you want to be even more secure you can have that api secret be used as a refresh token that can be used to retrieve an access token with an automated expiration.
SSL for all requests is also suggested.
Each API user has a unique API key. This key identifies them as a single user of the system. When dealing with more sensitive data, I've used client side certificates for auth, however Basic Auth + requiring SSL is usually sufficient.
When the request comes in, map the API key to the user and then determine if that user "owns" the resource they are trying to interact with.
The whole "determine the owner" part is a separate issue that can be tricky to do nicely in an API depending on how well the system was built. I can share how we've done that in the past as well, but figured that's a bit off topic.
Suggest you should consider using Oauth. In summary this is how it should work.
Each application making the API calls will need the respective application level APIkey for authorization through the Oauth process. Apikey here would just represent the application (client) identity.
Each end-user associated with the usage must authenticate themselves separately (independent of the apikey) during the Oauth authorization process. The users identity, associated context such as scope of authorization is then encoded into a token called access token.
Once the application obtains this access token, all subsequent API calls to access resources should use the access token, until expiry.
On the API implementation side, the access token validation should reveal the end-user context (including the scope of access that is granted during the Oauth process) and hence the access/authorization to use a specific resource can be managed by the resource server.
Related
My situation is this. I have a legacy Angular application which calls a Node API server. This Node server currently exposes a /login endpoint to which I pass a user/pwd from my Angular SPA. The Node server queries a local Active Directory instance (not ADFS) and if the user authenticates, it uses roles and privileges stored on the application database (not AD) to build a jwt containing this user's claims. The Angular application (there are actually 2) can then use the token contents to suppress menu options/views based on a user's permissions. On calling the API the right to use that endpoint is also evaluated against the passed in token.
We are now looking at moving our source of authentication to an oAuth2.0 provider such that customers can use their own ADFS or other identity provider. They will however need to retain control of authorization rules within my application itself, as administrators do not typically have access to Active Directory to maintain user rights therein.
I can't seem to find an OIDC pattern/workflow that addresses this use case. I was wondering if I could invoke the /authorize endpoint from my clients, but then pass the returned code into my existing Node server to invoke the /token endpoint. If that call was successful within Node then I thought I could keep building my custom JWT as I am now using a mix of information from my oAuth2 token/userinfo and the application database. I'm happy for my existing mechanisms to take care of token refreshes and revoking.
I think I'm making things harder by wanting to know my specific application claims within my client applications so that I can hide menu options. If it were just a case of protecting the API when called I'm guessing I could just do a lookup of permissions by sub every time a protected API was called.
I'm spooked that I can't find any posts of anyone doing anything similar. Am I missing the point of OIDC(to which I am very new!).
Thanks in advance...
Good question, because pretty much all real world authorization is based on domain specific claims, and this is often not explained well. The following notes describe the main behaviors to aim for, regardless of your provider. The Curity articles on scopes and claims provide further background on designing your authorization.
CONFIDENTIAL TOKENS
UIs can read claims from ID tokens, but should not read access tokens. Also, tokens returned to UIs should not contain sensitive data such as names, emails. There are two ways to keep tokens confidential:
The ID token should be a JWT with only a subject claim
The access token should be a JWT with only a subject claim, or should be an opaque token that is introspected
GETTING DOMAIN SPECIFIC CLAIMS IN UIs
How does a UI get the domain specific data it needs? The logical answer here is to send the access token to an API and get back one or both of these types of information:
Identity information from the token
Domain specific data that the API looks up
GETTING DOMAIN SPECIFIC CLAIMS IN APIs
How does an API get the domain specific data it needs from a JWT containing only a UUID subject claim? There are two options here:
The Authorization Server (AS) reaches out to domain specific data at the time of token issuance, to include custom claims in access tokens. The AS then stores the JWT and returns an opaque access token to the UI.
The API looks up domain specific claims when an access token is first received, and forms a Claims Principal consisting of both identity data and domain specific data. See my Node.js API code for an example.
MAPPING IDENTITY DATA TO BUSINESS DATA
At Curity we have a recent article on this topic that may also be useful to you for your migration. This will help you to design tokens and plan end-to-end flows so that the correct claims are made available to your APIs and UIs.
EXTERNAL IDENTITY PROVIDERS
These do not affect the architecture at all. Your UIs always redirect to the AS using OIDC, and the AS manages connections to the IDPs. The tokens issued to your applications are fully determined by the AS, regardless of whether the IDP used SAML etc.
You'll only get authentication from your OAuth provider. You'll have to manage authorization yourself. You won't be able to rely on OIDC in the SAML response or userinfo unless you can hook into the authentication process to inject the values you need. (AWS has a pre-token-gen hook that you can add custom claims to your SAML response.)
If I understand your current process correctly, you'll have to move the data you get from /userinfo to your application's database and provide a way for admins to manage those permissions.
I'm not sure this answer gives you enough information to figure out how to accomplish what you want. If you could let us know what frameworks and infrastructure you use, we might be able to point you to some specific tools that can help.
BACKGROUND
I have an application with a node backend and an angular frontend. The backend has two GraphQl endpoints:
/auth, which has methods like:
signIn, which authenticate an interactive user (basic usr/pwd) from my angular front and and returns an access token and a secure httpOnly refresh token (cookie);
refreshToken, which returns a new access token; and
signOut, which just revokes the refresh token.
/api, which contains the business rules, and authenticates the request by the access token received (stateless)
The angular frontend authenticates the user by calling the /auth/signIn endpoint, keeps the access token in memory, is unaware about the httpOnly refresh token, and creates a timer to call the /auth/refreshToken periodically.
PROBLEM
I need to grant access to my customers to access the /api programmatically too (e.g. from Zapier), so we are talking about an API-KEY, right? I was thinking about creating an API-KEY section in the SETTINGS area in the frontend and CRUDE methods in the /auth endpoint to maintain them. I would create a new special non interactive “user”, in the users table linked to the generated API-KEY so that, for instance, the user Zapier would be related to the API-KEY created to interact with Zapier and I could see its activity along the other users activities at the audit trail and easily revoke it by deleting that user.
QUESTION
Should I use a long term (?) access token as API-KEY? Wouldn't that defeat the purpose of using access tokens? My /api would no longer be stateless and I would have to check the existence of the access token for each request, right? It doesn’t seem the right choice. Is there a better approach?
Using the refresh token as API-KEY doesn’t seem to be an option to me, first, because it doesn't seem to be allowed to set a httpOnly cookie on the client side, second, because the logic to update the access token would be too complex to the user and third, because I wouldn't want to expose the /auth endpoint.
API Keys are very weak security so ultimately this depends on data sensitivity such as whether it is serious if an attacker can access your data easily for a long time.
I would favour a standard OAuth flow for the type of client - perhaps Client Credentials Grant - so that access tokens are used, which are valid for a limited time period, such as 30 minutes. Expiry and refresh coding is well documented online.
If it is a user app then maybe the app (or its back end) needs to do some work to get tokens correctly.
If the customer is writing code to call the API with code then they need to be given guidance on how to authenticate and manage expiry. These details are well documented online.
Attaching a token could even be managed by an outbound proxy if these users are very non technical, where the proxy deals with supplying a token.
I'm trying to accomplish the following scenario.
I have and API at the moment and one web app. I have also create a new oauth client on my auth server (keycloak), which follows the implicit grant. I also used jwks on my nodejs api to do the token verification.
Now I want to create an SDK that will target the same API.
The questions is how do I get the SDK to retrieve an access token from the auth server. The first thought is that I will have to create a new client oauth client on the authserver and then use the client credential flow to get the access token. However, I dont know what should the behaviour of my API be like. At the moment it used jwks against a single audience. How should it be configured to verify access tokens from multiple clients (potentially thousand of them)
If you want multiple clients to call your API they should all use the same audience, and your first level of security will work.
The audience in access tokens represents the API(s) the token can be used against.
You will then need to use something else to authorize API requests, depending on the type of client and what they are allowed to do.
Configure each type of client in your auth server so that you are in control and know who is calling the API.
You may have 1000 clients but only 4 levels of privilege - in which case only configuring 4 OAuth clients may make sense.
One OAuth option you can use is give different clients different scopes. Scopes can represent high level privileges.
If a particular client calls an addOrder operation but does not have an Orders scope you could return a 403 response.
Often though API authorization needs to go beyond OAuth checks and apply custom rules based on the end user privileges.
If you can provide more info on your scenario I could provide a more complete answer.
I may need to implement an OAuth2.0 server for an API I'm creating. This API would allow 3rd parties to perform actions on the user's behalf.
OAuth2.0 has 3 mains calls. First, there is a call to prompt the user for consent. This returns a code. The second is where the code is exchanged for a access token. Finally, the access token is used to call the API on the user's behalf.
For implementation, I was thinking the first call generates a random string which acts as a code. The code is then stored in a database with a pointer to the current User and a random HMAC Key, then the random data is returned to the 3rd party as the code.
When the 3rd party requests an access token, another piece of random data is generated and concatenated with the code. This string is signed using the HMAC key from Step 1, then this signed string and signature is returned with the signature to form the access token.
When the API call occurs, the hmac key corresponding to the provided access_token is retrieved from the database. The signature of the access_token is verified using the hmac key.
The user can revoke 3rd party access by simply removing an HMAC key from their list of authorized HMAC keys. Furthermore, but just signing random data, I can avoid storing every single access_token every created, and instead maintain a short list of hmac keys.
Anyway, this is my first attempt as thinking through this. Surprisingly, there is little information about implementing the server side of OAuth2.0 efficiently. I would prefer to keep as little information as possible in the database. The advantage of signing random data then later revoking the HMAC key is that I don't have to store every single access token generated by every single authorization call.
Thoughts needed! There has got to be a better way!
EDIT:
I'm NOT looking for an implementation. Thank you though! Also, I assume this whole system will run over HTTPs. Also, I'm talking about the pure OAuth2.0 flow, I'm not talking about OAuth1.0 with signatures and client keys. I'm asking how to design the cryptography behind an OAuth2.0 server that would work in a similar fashion to (for example) Google's OAuth2.0 flow works.
I don't have an exact answer to this, but let's try to put the pieces together -
i) I am not too sure if you need to save the authorization code in your database for long. This is what Facebook says -
New security restrictions for OAuth authorization codes
We will only allow authorization codes to be exchanged for access tokens once and will require that they be exchanged for an access
token within 10 minutes of their creation. This is in line with the
OAuth 2.0 Spec which from the start has stated that "authorization
codes MUST be short lived and single use". For more information, check
out our Authentication documentation.
See this link, https://developers.facebook.com/roadmap/completed-changes/ (December 5, changes).
ii) What about doing what you are doing till step 1, keep the authorization code and HMAC key in the DB. Let's have the authorization code for 10 mins (or whatever you feel is necessary) and then remove the authorization code.
iii) Let's say you have a single sign-in service that authenticates a client's credentials. When the client app hits the token exchange endpoint (auth code for access token) you'd need to fetch the HMAC key and return the access token. Why not add (some random data + timestamp + customerID/customer name(or something that can be used to uniquely identify the user)) and sign it with the key and return all this data as the access token.
You can think about using a new HMAC key perhaps and replacing the old one.
iv) When the client hits any API endpoint with the token, let the srvice internally call a CustomerIDExtractorService that fetches the HMAC key from the DB and decrypts the access token and returns the customerID to the relevant API. The independent process can then use to the customer ID to fetch data. So basically, I ask you to separate the login/token generation/token info extraction process to a separate unit.
Let's try to map this to how Google could be doing something like this
i) You use an app and sign in to Google Oauth. (Let a black box X from google handle the login).
ii) Your app hits the token exchange endpoint -> The service internally checks if the code is valid. If it is, the service combines some data + customerID and signs it and returns it to the app as an access token.
iii) The app now hits (say) the google+ endpoint. Internally, the service transfers the token to black box X, which decrypts the token and returns customer ID to G+ service. g+ then maps the C_ID to relevant customer data.
Another suggestion
Depending on the scope that the app requested, you can add more info to the access token. Maybe create a JSON object and add/remove fields according to the scope selected by the app. Sign the JSON string as the access token.
Seems your description started off OK, but then I must confess I could only partly follow your approach. AFAIK OAuth2 relies heavily on HTTPS rather than signed requests, although I guess you're free to use such.
I'm not sure about the concept you present to revoke access. Typically this would rely just on the access token (it should expire at some point in time, you could revoke it, and it could be renewed). If for API requests you are pulling keys for a userid then possibly your code is too closely tied to "user" concepts and not OAuth clients (with role, scope, resources)
In any case it's not a simple standard and I guess the discussion could go on quite long and even then I am not sure all could be covered. I trust you've reviewed the RFC at:
https://www.rfc-editor.org/rfc/rfc6749
I see also from your profile you're likely a Java developer. In such case it may be a good idea to review Spring-security-oauth2 at:
https://github.com/SpringSource/spring-security-oauth
If your solution won't use Java a lot of the issues you allude to in your question were approached and solved by such project, so it should give you lots of ideas. If you will use Java then it may help you a lot.
Hope it helps!
Actually most of implementations are using bearer token over https not mac in OAuth 2.0, check this presentation pages 54-56 about why prefer bearer ,on other hand spring implementation is not supporting MAC token for OAuth 2.0 and there is an open issue about it but it is still open
for time-being if you are looking for spring implementation demo you can check this source code but it is using data base to store tokens, and there is connection have to be done between the resource server and Authorization server, in this demo using data base.
one of open source implementation of Spring OAuth 2.0 is UAA of cloudfoundry I attend one session about it also they were telling that there is communication have to be done between both servers. link
I want to understand what token-based authentication means. I searched the internet but couldn't find anything understandable.
I think it's well explained here -- quoting just the key sentences of the long article:
The general concept behind a
token-based authentication system is
simple. Allow users to enter their
username and password in order to
obtain a token which allows them to
fetch a specific resource - without
using their username and password.
Once their token has been obtained,
the user can offer the token - which
offers access to a specific resource
for a time period - to the remote
site.
In other words: add one level of indirection for authentication -- instead of having to authenticate with username and password for each protected resource, the user authenticates that way once (within a session of limited duration), obtains a time-limited token in return, and uses that token for further authentication during the session.
Advantages are many -- e.g., the user could pass the token, once they've obtained it, on to some other automated system which they're willing to trust for a limited time and a limited set of resources, but would not be willing to trust with their username and password (i.e., with every resource they're allowed to access, forevermore or at least until they change their password).
If anything is still unclear, please edit your question to clarify WHAT isn't 100% clear to you, and I'm sure we can help you further.
From Auth0.com
Token-Based Authentication, relies on a signed token that is sent to
the server on each request.
What are the benefits of using a token-based approach?
Cross-domain / CORS: cookies + CORS don't play well across different domains. A token-based approach allows you to make AJAX
calls to any server, on any domain because you use an HTTP header
to transmit the user information.
Stateless (a.k.a. Server side scalability): there is no need to keep a session store, the token is a self-contained entity that conveys all the user information. The rest of the state lives in cookies or local storage on the client side.
CDN: you can serve all the assets of your app from a CDN (e.g. javascript, HTML, images, etc.), and your server side is just the API.
Decoupling: you are not tied to any particular authentication scheme. The token might be generated anywhere, hence your API can
be called from anywhere with a single way of authenticating those
calls.
Mobile ready: when you start working on a native platform (iOS, Android, Windows 8, etc.) cookies are not ideal when consuming a
token-based approach simplifies this a lot.
CSRF: since you are not relying on cookies, you don't need to protect against cross site requests (e.g. it would not be possible to
sib your site, generate a POST request and re-use the existing authentication cookie because there will be none).
Performance: we are not presenting any hard perf benchmarks here, but a network roundtrip (e.g. finding a session on database)
is likely to take more time than calculating an HMACSHA256 to
validate a token and parsing its contents.
A token is a piece of data which only Server X could possibly have created, and which contains enough data to identify a particular user.
You might present your login information and ask Server X for a token; and then you might present your token and ask Server X to perform some user-specific action.
Tokens are created using various combinations of various techniques from the field of cryptography as well as with input from the wider field of security research. If you decide to go and create your own token system, you had best be really smart.
A token is a piece of data created by server, and contains information to identify a particular user and token validity. The token will contain the user's information, as well as a special token code that user can pass to the server with every method that supports authentication, instead of passing a username and password directly.
Token-based authentication is a security technique that authenticates the users who attempt to log in to a server, a network, or some other secure system, using a security token provided by the server.
An authentication is successful if a user can prove to a server that he or she is a valid user by passing a security token. The service validates the security token and processes the user request.
After the token is validated by the service, it is used to establish security context for the client, so the service can make authorization decisions or audit activity for successive user requests.
Source (Web Archive)
Token Based (Security / Authentication)
This means that in order for us to prove that we’ve access we first have to receive the token. In a real-life scenario, the token could be an access card to the building, it could be the key to the lock to your house. In order for you to retrieve a key card for your office or the key to your home, you first need to prove who you are and that you in fact do have access to that token. It could be something as simple as showing someone your ID or giving them a secret password. So imagine I need to get access to my office. I go down to the security office, I show them my ID, and they give me this token, which lets me into the building. Now I have unrestricted access to do whatever I want inside the building, as long as I have my token with me.
What’s the benefit of token-based security?
If we think back on the insecure API, what we had to do in that case was that we had to provide our password for everything that we wanted to do.
Imagine that every time we enter a door in our office, we have to give everyone sitting next to the door our password. Now that would be pretty bad because that means that anyone inside our office could take our password and impersonate us, and that’s pretty bad. Instead, what we do is that we retrieve the token, of course together with the password, but we retrieve that from one person. And then we can use this token wherever we want inside the building. Of course, if we lose the token, we have the same problem as if someone else knew our password, but that leads us to things like how do we make sure that if we lose the token, we can revoke the access, and maybe the token shouldn’t live for longer than 24 hours, so the next day that we come to the office, we need to show our ID again. But still, there’s just one person that we show the ID to, and that’s the security guard sitting where we retrieve the tokens.
The question is old and the technology has advanced, here is the current state:
JSON Web Token (JWT) is a JSON-based open standard (RFC 7519) for passing claims between parties in web application environment. The tokens are designed to be compact, URL-safe and usable especially in web browser single sign-on (SSO) context.
https://en.wikipedia.org/wiki/JSON_Web_Token
It's just hash which is associated with user in database or some other way. That token can be used to authenticate and then authorize a user access related contents of the application. To retrieve this token on client side login is required. After first time login you need to save retrieved token not any other data like session, session id because here everything is token to access other resources of application.
Token is used to assure the authenticity of the user.
UPDATES:
In current time, We have more advanced token based technology called JWT (Json Web Token). This technology helps to use same token in multiple systems and we call it single sign-on.
Basically JSON Based Token contains information about user details and token expiry details. So that information can be used to further authenticate or reject the request if token is invalid or expired based on details.
When you register for a new website, often you are sent an email to activate your account. That email typically contains a link to click on. Part of that link, contains a token, the server knows about this token and can associate it with your account. The token would usually have an expiry date associated with it, so you may only have an hour to click on the link and activate your account. None of this would be possible with cookies or session variables, since its unknown what device or browser the customer is using to check emails.