I have been reading a lot about OAuth 2 flow recently, and I wanted to ask if this is applicable to the app that I am building, and what type of security I should be using.
- We have a native ios/android and angular SPA app.
- We build/own/control our own backend apis, and only our frontend apps can(should) communicate with these apis.
- User logs in on a form, we validate credentials on backend, and return a JWT back, which is then used for subsequent requests. Access to most apis is restricted to logged in users, other apis are open to the net to allow users to register.
I cannot see a use case here for OAuth here, however, everything I am reading seems to suggest that it is required. We will not be delegating access to third party systems, we simply only want to validate our own customers, and only allow them to access our apis via our front end apps, after they have logged.
Is the approach I have outlined which we are currently doing correct, or do I need to implement OAuth Authorization Code flow, and if so can you please explain why ?
I am currently in situation where I have to decide when to implement security measures. So the question is simple, is it better to implement authorization and authentication methods right off the bat in the beginning of the project, OR at the end of the project, before the first release?
Things I considered: at the end, one would make quite a bit of changes to the API; at the beginning it is time consuming, if the client wants to see first results soon.
Let’s assume that a client has the client secret exposed somewhere. What are the risks that the client and its users are exposed to? Are those the same as having implemented the implicit flow from the begin with?
I would say that, the risk here is for an attacker stealing a code, and since the client secret is available, assuming no other form of client authentication is performed, then the attacker would be able to exchange the code to token. So it looks like it’s similar with the risks of implicit flow, but a bit more secure since by default the tokens are not exposed in the user-agent (implicit flow could use for example response_mode=form_post and avoid that scenario)
I am working on a hobby project which will involve a web server (hosted and owned by me) and a native app (which will communicate with the web server periodically) an end-user can install via a deb/rpm package. This native app has no traditional UI (besides via command line) and can be installed on browser-less environments. Additionally, I’m trying to avoid registering custom URL schemes. As such, I do not wish to use redirect flows, if possible.
The web server and the native app will both be open source and the code will be visible to everyone, but I suppose it shouldn’t matter in the context of authentication. However, I wanted to point that out in case it matters.
So far, during my research, I’ve come across two mechanisms which seem suitable for what I am trying to achieve:
- Resource Owner Password Credentials Grant
- Device Authorization Grant
Unfortunately, I’ve come across a lot of articles and blogs stating that Resource Owner Password Credentials Grant should no longer be used. Not sure how much weight I should give these articles, but I’m leaning towards Device Authorization Grant for now.
From my understanding, one of the steps involved in this grant is the client will continuously poll the server to check if the user has authenticated the client. However, instead of polling the server, why not flip the place where the code is entered?
In other words, instead of the client/device displaying a code to the user and the user then entering the code on the server, why not display the code on the server and have the user enter the code into the client? This way the client doesn’t have to needlessly poll the server? Does this not achieve the same thing? I’m really not sure though. I want to ensure I’m not missing something before I implement this.
This is how I envision the general flow for users using my project:
- The user would register an account on my site (i.e, the web server). This is just a traditional username and password authentication.
- The user can then download and install the deb/rpm package which contains my native app. Although, it should be noted that there’s obviously nothing preventing the user from installing the package without registering an account on the server. The whole point of this authentication is create a link between the account on the server and the native app.
- Prior to enabling the daemon/service functionality of the native app, the user will need to authenticate the native app to the server.
- To do so, the user can log into the server (using their regular username/password creds) and generate a temporary token.
- The user can then use the CLI functionality of the native app to use this temporary token. For example, the user may type
my_app_executable authenticate, where
my_app_executable is the binary executable and
authenticate is the parameter.
- This will prompt the user to enter their username and the temporary token.
- The app will then send the entered username and temp token to the server which will validate this combination. If it’s valid, the server will send a access token back to the app.
- The app can then use this access token to communicate with the server. Authentication complete.
Based on this, I have a couple of questions:
- Does this flow seem secure? Is there an aspect of this that I’m overlooking?
- Is it okay to more or less permanently encrypt and persist this access token on the filesystem? If the user turns off the native app for months and then they turn it back on, I would like it to function normally without making the user authenticate again. I suppose I’ll need to implement a way to revoke an access token, and I’m thinking about tracking this in the database on the server side. This would mean that for each HTTP request from the app to the server, the server will need to make a DB check to ensure the access token hasn’t been revoked.
We are building a public-facing API. The consumers of this API will be business partners of ours – we will probably have a personal relationship with each one, and I suspect there will only ever be 10-40 of these customers. So we’re not dealing with the same problems that e.g. Spotify/Facebook might with their public APIs.
We want to give each user different API read permissions, so some level of authorization is required.
We were going to issue each customer with an API key, and store the related permissions in a table. But now we’re wondering if we should implement JWTs to handle this.
Pros of API keys:
- Simple. Easy for the clients to implement (fairly important for us)
- Makes rate limiting simpler, as there will be fewer auth calls.
- Cheaper (we are using AWS lambda so paying per request)
- Quicker for us to build too
Pros of JWTs
- More established way of handling authorization. No need to reinvent the wheel.
- Avoid any unforeseen pitfalls around implementing your own access mechanism
- Fewer database look-ups on our end (but presumably slower flow overall)
- …any others I’ve missed here?
We’re leaning towards API keys for simplicity, but want to ensure we’re not missing something important.
I have an app that revolves entirely around Spotify. I have followed the authorization guide from Spotify and am using the Authorization Code Flow so the access token can be refreshed. My thinking was that this will prevent them from having to log back into Spotify each time they return to the app, but I’m not sure how to do this securely.
For authorization, they are taken to the Spotify page to authenticate and grant my app access to to the requested scopes. After being redirected to my React application, the authorization code is forwarded to my REST API server so it can grab an access and refresh token.
At this point, I’m wondering:
- Should I store the refresh token in the DB? Wouldn’t I need to encrypt it?
- Should I return the access token to my React app so that it can include it in subsequent requests to my API?
Since I’m storing their Spotify id in my DB, it seems like I could use the access token to hit https://api.spotify.com/v1/me to get this id and look them up in my database to make sure they’re authorized to access the requested resources both on my server and on Spotify’s in one shot. It seems like this would prevent them from needing to have a separate authentication just for my app, since everything is tied to Spotify anyway.
My concern with this approach is that it seems insecure. If a malicious entity acquires one of my user’s tokens, I’m afraid they would have eternal access, since I’m refreshing the token on behalf of the user as specified by the Authorization Code Flow.
So, I’m considering having my own authentication (AWS Cognito) in addition to Spotify authorization.
It seems like leveraging Cognito for authentication would allow me to make sure it’s them just by verifying the JWT. Then, I can look them up in my DB by the JWT sub. This seems like the cleaner way to do things, but it leaves me with questions:
- Wouldn’t I then need to store their Spotify access token in my DB as well? Wouldn’t I need to encrypt it?
- Is this this some sort of anti-pattern, since the user has to sign in with me and sign in with Spotify? I can’t seem to rationalize why this is different from any other federated idP flow, like how Cognito lets FB, Google, etc. be leveraged for sign in to authenticate users with my app. They’re signing in with Spotify already, so I’m confused as to why there needs to be an extra step of also having to sign into my app.
I have read the OAuth 2.0 RFC 6749 documentation, the OpenID Connect documentation
I have also read a plethora of posts (and the links within them), including, but not limited to:
- OAuth2 and Authentication
- Storing third party API tokens in a database
- Should client have access to 3rd party API access token?
My employer will not accept re-directions to the authorization server in our single page app. But I do not want to resort to using the resource owner password flow.
Since we own and trust the client is it acceptable to embed the authorization server in our client via an iframe, prevent other sites from embedding it via the Content-Security-Policy header, and use the Authorization code flow + PKCE?
If it helps we are using IdenityServer4.
RFC7636 states “The operating systems must allow a custom URI scheme to be registered by multiple applications.” Are web apps vulnerable to this attack? Could a web app link open a malicious app via a custom URI scheme?
Why do we need to ask authorization server for
Authorization code and then exchange
Authorization code to
Access token on the same server? Why not to return
Access token directly, without issuing
Authorization code? I do understand that it is specified by the standard but there should be some logic behind this.
We are currently evaluating which authorization type to use for our production AppSync APIs.
As per AWS docs(https://docs.aws.amazon.com/appsync/latest/devguide/security.html, https://aws.amazon.com/blogs/mobile/using-multiple-authorization-types-with-aws-appsync-graphql-apis/ ), AppSync supports multiple authorization types – like API Key based (passing a static API Key), IAM role based.
My questions are around the differences between API Key based approach & IAM based one:
1)why is using a static api-key considered bad for production use cases if all calls to AppSync are HTTPS based(which has good encryption)?
2)Why can’t we use a short lived token of our own along with API key & validate that token in a resolver? This would bring in some dynamism as the token is shortlived , so even if somebody hacks and gets this token ; by them time a replay happens the token is already expired?
3)The previous manual token approach seems similar to using an IAM role for Authorization. How safer would it be to use Amazon Cognito’s IAM Auth. roles for this be than a manual token approach? Does the SIGV4 standard used by AWS help in anyway here?