Understanding oAuth implicit flow - oauth

I'm working with the New Twitch API and I wish to get data from and end point using javascript.
Endpoint https://dev.twitch.tv/docs/api/reference/#get-streams
For the means of testing, I'm hitting the endpoint with Postman and it's working.
According to the docs, I need to provide a client-id which I can get from my developer dashboard and I add this as a header in Postman.
What I'm confused about is that it seems for as long as you have someones client-id (which is going to be exposed when using JS) anyone can hit this endpoint? What stops someone taking my client-id or me taking someone elses and using it for their/my own purposes and what are the risks with that?

In general, it's the Redirection URL that's the lynchpin.
The flow works like this:
You register your app at Twitch. As part of this step, you specify your redirection URL (https://dev.twitch.tv/docs/authentication/#registration)
A user visits a web page that makes use of the API
The user needs to authenticate. The web page hands off to the Twitch OAUTH authentication page, passing along its Client ID
The user authenticates with Twitch
Twitch redirects the user to the Redirection URL set up in step #1, along with a Bearer Token.
As you can see in step 5, the token is only sent back to your Redirection URL. If another website tried to get a user authenticated using your Client ID they would never receive back the token.
The area I think you could run into trouble is rate limiting. Twitch limits you to 30 queries per minute with a Client ID and no Bearer Token or 120 queries per minute with both. If a malicious user is using your Client ID then it would eat up your rate limit. https://dev.twitch.tv/docs/api/guide/

Related

Understanding the flow of OAuth2

I'm new to OAuth2 and I'm trying to understand the whole flow of things. For context, I'm thinking of making a web dashboard where users log in via Discord's OAuth2 API.
This is how I think the flow works based on my understanding so far:
User goes to my site and clicks a login link
My site redirects them to Discord with my client ID and a redirect URL #1 in the query string
Discord redirects them back to my site at redirect URL #1 with an authorisation code in the query string
My site takes this authorisation code and along with my client ID, client secret and redirect URL #2, uses all these to fetch an access token and refresh token from Discord
If I do get an access token, that means the user is now "logged in" (authorisation code worked)
My site finally redirects the user to a page and is now free to send requests to Discord's API with the access token, while saving the access token and refresh token. Just for example, say the page states their Discord username
I'm learning from this guide, and what confuses me is this code snippet from the guide. At line 5, it provides the redirect URL #2 mentioned above, in the query string. I'm not sure what it's for.
Also, I'm not very sure how to continue once I have the access token. If multiple users log in, I'd have multiple access tokens on hand. Say a user wants to access the page again, how do I uniquely identify them and know which access token to use to send requests to Discord's API? (for this example, the request would give me their username which I'd display on the page)
Yeah, I probably got a lot of concepts wrong. Any clarification would be greatly appreciated!
Edit: I've done more research into this, and found a much better guide here.
For my question about the second redirect URL, the examples in the official documentation specify a redirect_uri when doing both an access token and a refresh token exchange. However, this new guide makes do without for their access token exchange. Perhaps they missed it out? As this other stack overflow question says:
As an added measure of security, the server should verify that the redirect URL in this request matches exactly the redirect URL that was included in the initial authorization request for this authorization code. If the redirect URL does not match, the server rejects the request with an error.
I suppose this means that after the first access token exchange, any refresh token exchanges or straight up API requests with access tokens need to match the original redirect_uri of said first access token exchange. So I should use one and only one redirect_uri, and the refresh token exchanges/API requests do not actually use the redirect_uri, rather it's used for further security.
As for the whole login procedure, it seems I have to link the access & refresh tokens I obtain to a user session, and for that I'll look into using this passport strategy, passport-discord. Then, once the session expires, I'll discard the two tokens, and they'll have to click login again, but I can make use of this prompt option:
prompt controls how the authorization flow handles existing authorizations. If a user has previously authorized your application with the requested scopes and prompt is set to consent, it will request them to reapprove their authorisation. If set to none, it will skip the authorization screen and redirect them back to your redirect URI without requesting their authorization.
From there I think I'd just store the new access and refresh tokens associated with that user.
I'd really appreciate if any mistakes in my thought process could be pointed out!
Your summary seems good to me Mr Cloud - worth clarifying whether you are developing an SPA or (old) web app with a server side. Most commonly the first is cookieless, whereas the second stores a refresh token in a cookie. A key thing is to understand what the OAuth message workflow looks like. For SPAs and APIs this write up of mine may help you clarify what you want: https://authguidance.com/2017/09/26/basicspa-oauthworkflow/
Happy to answer any follow on questions ..
You can use the implicit grant to use with SPA
https://discord.com/developers/docs/topics/oauth2#implicit-grant

OAuth 2.0 Single-use Access Token for unauthenticated user via IdentityServer4

I apologies in advance for incorrect use of oauth terms.
I have 4 "parties" as follows (intentionally not using oauth terms where possible):
End-user in a browser (javascript)
Our website (aspnet)
Our web api (aspnet)
Our auth server (aspnet utilising identityserver 4)
My usage scenario is that we only want the API to be called by a browser that has requested a page from the website first. Whilst the API doesn't release sensitive information, we would like to introduce a layer of complexity with regards to the API being spammed.
Our end user's will not be logged in.
I imagine such a flow being akin:
Browser requests a certain page from the website (one that will likely lead to js making an api call)
Website requests token from auth server
Auth server verifies token request came from website (the server itself)
Auth server returns a token to the website
Website returns page including the access token
Browser is able to make a request to api using token
Although convoluted, I believe this is at least similar to the Client Access Grant flow?
These tokens could then be throttled either by website or auth server.
Yes, I'm aware that this doesn't protect the api from numerous other vectors, but it does eliminate the simplest of cases which is all we're looking to achieve for now. I'll add, I didn't define this requirement, I'm simply trying to find a way to achieve it utilising techs out there instead of making the mistake of rolling anything of my own.
Could someone confirm/deny that there is an oauth flow I could use here? Any sample projects using the given flow and IdentityServer?
IdentityServer3 / non-aspnet[core/5] examples are fine, I can translate.
What you describe is the Client Credentials Grant where your website (client) gets an access token from identityserver (auth server). That access token can then be used to call endpoints on your web API (resource server).
The token is a bearer token and can be used by anyone who has it, so if you are comfortable with your website passing it back to a browser on an HTTP response, then it will work just fine.
I'm not sure what you mean by throttling the tokens - once minted they are valid for their lifetime. I guess you can keep the time-to-live very short to achieve the single usage you want though.

Access LinkedIn REST API without front-end (e.g. OAuth2 redirect)

Goal
Fetch a company's updates save them locally in a background task
Problem
This should be done as a backend service without any real user interaction. We could provide a user account to use, but the authentication is a problem: There is literally no one to answer the OAuth redirect and there is no public redirect URL to configure, since it's a background service.
Is there any way to access the API without having a redirect URL or a real user?
You can get an initial access token in a regular front end flow, for you as the app developer i.e yourself as the LinkedIn user. Once you've got that, you can store it in the backend and use it for 60 days to get access to the LinkedIn APIs.
After 60 days you need to refresh the token as documented in:
https://developer.linkedin.com/documents/handling-errors-invalid-tokens
Unfortunately LinkedIn does not (yet) support an autonomous refresh flow where your app can get a new access token by presenting a refresh token on a backchannel. So the developer will have to refresh the access token by a manual login every 2 months.
Well, it is still all HTTP and HTML, so in fact there is no real reason to show the OAuth dialog to a user, as long you can strip out the necessary parts in the HTML authentication dialog and send a valid response back to the server, using the username and password from the user (which you can obtain from him, or save it yourself in a config file if it is you).
Note that there might be a legal issue if LinkedIn demands you to actually show the dialog, beside that, there is no technical need.

How to tie oAuth2 tokens to an identity?

I'm currently working on a project for content partners network. I would like to provide Login with YouTube feature, as well as other stuff.
So I'm currently implementing oAuth2 authentication, and when that succeeds I get access_token and refresh_token, but no identification (could not know who do tokens belong to, just by having them).
Is there any kind of global YouTube/Google User ID within https://www.googleapis.com/auth/youtube.readonly scope (or any other scope) that I could get with my tokens?
All you need to do is a channels->list call with "mine" = true. That will give channel id and all the information about user(channel).
GET https://www.googleapis.com/youtube/v3/channels?part=id%2C+snippet%2C+brandingSettings%2C+contentDetails%2C+invideoPromotion%2C+statistics%2C+topicDetails&mine=true&key={YOUR_API_KEY}
I am not familiar with this API, but the etag should change if the content at that URL changes, and could change at any time even if the content has not changed.
https://developers.google.com/youtube/2.0/developers_guide_protocol_profiles
To request the currently logged-in user's profile, send a GET request to the following URL. Note: For this request, you must provide an authentication token, which enables YouTube to identify the user.
https://gdata.youtube.com/feeds/api/users/default
You kinda sorta might be able to do this with a cookie.
1) you present your page with a set-cookie that redirects to the oauth2 google page.
2) user auths with google sends a redirect to the browser going back to your page.
3) the browser is redirected to your redirect page with your cookie.
Not great, but I think it should work.

OAuth - How is it secure?

I am writing some code to get Twitter and Instagram feed. Before I can write any code, I keep wanting to get a good understanding of oAuth because I have this nagging feeling that it is not all that secure and that most times, for instance when accessing public tweets, it is an unnecessary hassel. I started reading the oAuth 2 specification to get a better understanding, I am still in the middle of it. And I have a host of questions.
Let's use Twitter as an example.
A user accesses your site. You redirect them to Twitter for authentication and to obtain the authorization_grant code.
I understand this part is secure because the user authentication and the redirect to your website will happen over ssl. Is it enough for Twitter to support SSL or does your site also have to support SSL for the redirect to be secure? You wouldn't want the authorization code to be transferred insecurely, right?
Now that you have your authorization_grant code, your site will send a request to Twitter to obtain an access token. When making this request your site will send the authorization_grant code, your client id and client secret. Again I guess the communication is secure because this will happen over ssl. But what if the site has included the client id and secret somewhere in its HTML or Javascript, especially if it is a static site with no server side code?
Should the redirect url always be handled by server side code and the server side code should make the request for access token without ever going through HTML or Javascript?
Once you have the access token, you will include it in your request to obtain the user's tweets, to post tweets on their behalf etc. Again if the site in question were to include the access token inside its HTML or JavaScript along with the client id and secret, that would be pretty insecure, right?
It seems all the security of oAuth stems from ssl and the client's ability to keep their client secret secret. Am I right in this conclusion?
Another thing - in the first step of the process, when the client redirects the user to Twitter to authenticate and obtain the authorization_grant code, they could send in their client id and secret and get the access token directly instead of making a second request for it. I think this is what they mean by the implicit method in the specification.
So, why was this extra step of sending a second request to obtain access token added in the specification? Does it increase security?
I am not sure about twitter API, I am talking with respect to stackexchange API
https://api.stackexchange.com/docs/authentication
Again I guess the communication is secure because this will happen
over ssl. But what if the site has included the client id and secret
somewhere in its HTML or Javascript, especially if it is a static site
with no server side code?
client_secret is send only in the case of explicit flow. Explicit flow should be used by server side application and care should be taken to keep the client_secret safe.
So, why was this extra step of sending a second request to obtain
access token added in the specification?
Well, Implicit flow is less secure than explicit flow since access toke is send to the user agent. But there is an attribute expire in the case of implicit flow which will get expired unless you have specified scope as no_expiry. Also server side flow can be used only by the apps that are registerd
It seems all the security of oAuth stems from ssl and the client's
ability to keep their client secret secret. Am I right in this
conclusion?
Again client_secret will be available in server side flow. But yes, client should take care that access_token is not given out
Check out this link. It gives an example of possible vulnerability in ouath.

Resources