Can't modify user private data with Client Credential Flow by Spotify Web API - api

Is there any method to modify i.e. playlist by Web API by with console based application in Client Credential Flow ?
https://developer.spotify.com/web-api/authorization-guide/#client-credentials-flow
Propably not, but maybe I am wrong ? I want to modify only my user's data.
Here I created issue at API specification
https://github.com/spotify/web-api/issues/165

One of the benefits with the Client Credentials oAuth 2.0 flow is that applications can make authenticated requests to a web service without a need to involve an end user. Since a user isn't involved, the requests that can be made from the application is limited. For example, using Spotify's API, you can still make requests to retrieve track metadata, playlist contents, and search for albums. Any endpoint that requires a scope can't be used since it requires user interaction.
So using Client Credentials simply doesn't make sense if you're interested in making requests on behalf of a user, or if you want to access private data since the user needs to give you permission first.
You need to use Implicit Grant or Authentication Code Flow for this. I advise that you read further about the supported oAuth 2.0 flows in the Authorization Guide. One of the benefits of using the Authorization Code flow is that you'll also retrieve a new refresh token, which you can use to retrieve access tokens indefinitely. It however requires you to write a web service that accepts an authorization code and exchanges it for the tokens. The Implicit Grant flow doesn't return a refresh token, so it's only possible to use for one hour until the access token has expired.

Related

What's the proper way to implement a "static" authorization token feature using OIDC (or OAuth2)

I am exploring possible solutions for creating something like "API Keys" to consume my API. The goal is to allow for users to generate one or many "API Keys" from the web app and use the static generated key from the CLI app.
The web app and the client app are already using standard OIDC with JWT tokens for authentication and authorization using RBAC (role-based access control). The CLI app can already authenticate the user through the standard browser flow (redirects the user to the browser to authenticate and exchange the token back to the client).
The "API Keys" solution I am trying to achieve should have some fine-grained options where it won't authenticate as the user, but will authorize the client on behalf of the user (something like the GitHub Personal Access Token).
To me it seems like a "solved problem" as multiple services provide this kind of feature and my goal is to do it the most standard way possible using the Oauth2/OIDC protocols but I can't find details on what parts of the protocols should be used.
Can anybody provide any guidance on how it is supposed to be done using the Oauth2/OIDC entities?
Can I achieve it by only using Role-based access control or do I need Resource-based access control?
It went through the path of creating a new client for each "API Key" created, but it didn't feel right to create so many clients in the realm.
Any guidance or links to any materials are appreciated.
Can anybody provide any guidance on how it is supposed to be done
using the Oauth2/OIDC entities?
OIDC is based on OAUth 2.0 so after user login you have id tokens, access token and refresh token on the backend side. To generate new access token without asking user for authentication data you should use refresh token: https://oauth.net/2/refresh-tokens/
Can I achieve it by only using Role-based access control or do I need
Resource-based access control?
resource-based access control is more flexible solution here, but if you business requirement is not complex, then role based might be enough.
It went through the path of creating a new client for each "API Key"
created, but it didn't feel right to create so many clients in the
realm.
It is one application so you should use one client with specific configuration for access token and roles/permissions for users.
Update:
We can use GitHub as an example:
User is authenticated during login
for OIDC code is exchanged for id token, access token and refresh token
session for user is set for web browser
User can request access token
in GitHub authenticated user can request github.com/settings/personal-access-tokens/new endpoint
request is accepted, because user is authenticated based on session
backend service responsible for returning access token can obtain new access token using refresh token from point 1.
access token is returned to GitHub user
To call your API in an OAuth way, CLI users must authenticate periodically. Resulting access tokens can be long lived, as for GitHub keys, if you judge that secure enough. The access token returned can be used exactly like an API key. There may be a little friction here between usability and security.
CONSOLE FLOW
The classic flow for a console app is to use the Native Apps Desktop Flow from RFC8252. This involves the user interactively signing in using the code flow, then receiving the response on a loopback URL. It is an interactive experience, but should only be required occasionally, as for GitHub tokens.
API KEYS
The access token returned is sent in the authorization header and you can use it as an API key. Access tokens can use a reference token format. to make them shorter and confidential, to prevent information disclosure. These will be more natural in a CLI.
API AUTHORIZATION
When your API is called, it must receive access tokens containing scopes and claims, to identify the user. This will enable you to authorize correctly and lock down permissions.
{
sub: 586368,
scope: repos_write,
topic: mobile,
subscription_level: silver
exp: ?
}
TOKEN REFRESH
Sometimes CLI access tokens are long lived, for convenience. A more secure option is for the CLI to use token refresh. It can then store a refresh token in OS secure storage, then renew access tokens seamlessly. My blog post has some screenshots on how this looks, and a desktop app that does not require login upon restart. The CLI needs to deal with expired access tokens and handle 401 responses.
DYNAMIC CLIENT REGISTRATION
Some developer portal scenarios use DCR. It is another option in your security toolbox. It could potentially enable a silent client per CLI user:
User runs a standard authentication flow with a DCR scope
This returns an access token that enables client registration
The resulting token is used to register a new client
This could potentially be a client ID and client secret used in a CLI
Afterwards, the user and client are bound together. Probably not immediately relevant, but worth knowing about.

Workflow to implement Google OAuth2.0

I'm trying to implement Google authentication for my app and the below is the workflow I'm trying to set up.
First, user will authenticate with Google and obtain an access token.
User will make requests with this token to backend services.
Backend services will check with Google to validate these token
Once validated, backend services will send information requested by client back to users
And I have a couple question around it:
Is this the correct way to implement it?
How to avoid check with Google for every single request between Backend and Frontend?
It's sort of the correct way. It depends on the details. If I understand correctly, you are in control of the front and backend (these are both your applications). If this is the case, then you would rather use Google services only to authenticate the user (so use an OpenID Connect flow to get an ID token to verify the user's identity). After that, you would have your backend either issue an access token or establish a session with your frontend. Then you wouldn't have to ask Google for the token's validity every time someone makes a request to your backend.
An access token that you get from Google, Facebook, etc. is meant to be used with their APIs. You could use it to authorize access to your own backend, but you then have to call Google on every request to verify the token. You are also tightly coupled to Google's details of the access token usage — what scopes are available, what data is returned with the token, expiration times, etc.
If the access token is a JWT, then you can verify it on your own in your backend. You don't have to call the issuer every time. But, if I remember correctly, Google issues opaque tokens, so this is not the way to go here.
To sum up. If you're in control of the front and back end, then authenticate with Google, then start a session between your applications. This will be simpler to maintain and also safer, as you wouldn't have to handle tokens in the browser.

Oauth 2.0 and OpenId Connect for REST API authentication and authorization

After having read books and watched videos on OAuth, OIDC, PKCE, JWT, etc. I still have no idea on how to use all of these for my app (a secured REST API).
My use case is fairly simple. I want my users to be able to login with Google, Amazon, Okta or whatever and the only info I want from them is the email address they used to login, nothing else. After their first login, their email will be added to a database and in a separate process I will grant them some permissions (what resources they can access).
So let's imagine a standard authorization code flow and let's fast forward to the access token part. The redirect URI has been called, we are in my client (somewhere is my backend/API) where I retrieve an access token. At this point the user has been successfully authenticated.
But what now ?
I don't care about Google anymore (do I still need the access token ?), but I still want to check if the user can use my API for each request and is able to access the API resources depending on his permissions.
How do I keep the user authenticated (for like 2h only) and check his permissions ? A session Cookie, a Token or something else with an expiration time ?
Do I need my own authorization server to check if the user has access to the resource he is requesting ?
Considering my requirements, do I need PKCE if the API is accessed from an SPA or a mobile app ? Wouldn't the authorization code flow be enough - the SPA or mobile app retrieve an authorization code, then call the callback endpoint from the API ?
And the more important question is, do I ask the right questions or am I completely off track and it's not how it's supposed to work ?
In terms of your questions:
Your API needs an access token on every request
A stateless session is managed by sending the access token on every request
It is recommended to use your own Authorization Server that manages redirecting to social providers - this will simplify your UIs and APIs which only need to handle one type of token - also this means you are in control of the tokens your apps use
Yes - use PKCE for public clients - the Authorization Server and UI security libraries will handle this for you
Your use case is not simple at all on a technical level and requires a lot of understanding. A good starting point is to understand these aspects:
Role of UI and what a coded solution looks like
Role of Authorization Server and its configuration
Role of API and what a coded solution looks like
Open Id Connect messages used
These links of mine may be useful for browsing:
Initial code sample and tutorial
Message Workflow including PKCE
Given an access token, both the UI and API can potentially get the email via step 12 in the second link to lookup user info.

OAuth 2 authentication for both iframe and api

I'm integrating several web sites/services into my application. I use iframes (or webview for Vue Electron) for UI integration and I also use API to implement cross-communication between those services.
At the moment I have to go through OAuth 2 authentication twice for each service: once as part of natural authentication in iframe and another when I ask the user to give me access to this service (for api reasons).
Is there any way to streamline this process?
The state of the art response would be to modify your application completely.
You should have 1 SPA application and not iframe
This application would authenticate to get OAuth2 token
This application would then call the backend (access multiple backend, or access on api management layer that call backends).
Thing is, with this you can have 2 strategies :
give all permission (scope) at 1st authentication
give the smalled scope possible at 1st authentication, then when needed "reauthenticate" (in fact validate new scope) to get new access token
When an API want to call another API, you have also 3 strategies:
you simply use the same client token the API receive to the service your API call (no human interaction needed)
your API generate a token from a service account (using ROPC authentication scheme) or via a client credential scheme (the access token will be valid but usually not be bind to a real user), (no human interaction needed). (the API will be the client of the 2nd API)
your identity provider have an endpoint to transform access token : Your API can give the client access token, and authorization server will transform this with the client_id of your API. You send this token to 2ndAPI ( token will show subject of your UI application, but client ID will be the 1st API clientId) (no human interaction needed)
Now if you use IFrame with multiple sub-application on the same domain (the domain need to be exactly the same!), it is possible to share the same access token for instance via local storage. (security is not top notch)
You will probably need to authenticate with a bigger scope list sometime but it is your only option. You will simulate a single page application, but issue is that you will have potentially different client_id depending first application you authenticate to.
Edit: Multiple authorization server
From your comment, you have multiple authorization server. One strategy could be to ask user to authenticate, your application can then get an access_token and a refresh_token.
Depending on your authorization server, refresh_token can be used a lot / on a long period of time, so that if you store it somewhere, the next time the user visit your application, your application can silently get an access_token from this refresh token. Your application have then access to remove api without newer interaction from your user.
Of course, this means you have to save this token the most safely you can.
By using OpenID Connect you could combine authentication and authorization in a one step and get both an id_token to logon your user to your app as well as an access_token to access APIs in a single authentication response.

Understanding Oauth2

I am creating a REST inspired API for a Learning Management System. It will expose data such as users, classes, grades, courses etc. I have defined all the resources I want to expose, given them each an endpoint URL, and defined the JSON resource structures that are returned.
I now want to understand how to secure the API using Oauth2 (I don't want to use Oauth1). Am I correct in the assumption that my API will play the part of both the Authorization Server & the Resource Server? Also, what grant type / flow should I be researching?
A lot of the tutorials seem to focus on using Oauth2 to login using facebook credentials etc - but I just want to use it to secure my API and allow my users access to my API (either through a client, or directly). The access permissions for the API should follow the individual users access permissions that are already handled within our system.
Sorry for the scatter-gun questions - I just don't understand oauth2 enough to know where to direct my research. Any help would be greatly appreciated, and any pointers to simple tutorials for the correct use case would be great too.
FYI - The system is built on a LAMP stack using Drupal 6 (old, I know).
Well your assumption is correct the authorization server and the resource server can be on the same server or in the same API.
So how the OAuth2 basically works you have some kind of client(Server, Browser) Authorization API will authorize with Access Token to use your resource API which is then sent in the the Authorization HTTP header on every resource request.
So what I success is that when the user logs in, you identify the user and generate the Access Token immediately to the client. Now you can put some data inside the Access Token e.g. userId, permissions etc. Now when the Access Token hits your resource endpoint you can identify the user and check the permissions. Also you can just make the Access Token dumb so it doesn't contain any data then when you validate it from Authorization API(on Access Token creation you have to store info about the user to Authorization DB), you can get the info you need on the response e.g. userId, permissions etc.
What grant type flow to use, this is basically up to question what kind of clients are using your Authorization API and how secure you want the Authorization to be. E.g. implicit grant is for browser based clients which can handle redirections and e.g. Client Credentials grant is for (server-to-server) communication.
Reference here
To start with, you can use existing providers like WSO2 API Manager for supporting your system. It is well documented and has many REST APIs for this.