Need an OAuth2 server that supports "client credentials" grant type - authentication

I need to get authenticated using OAuth2 client credentials as the grant type. The app would need to call the OAuth2 server with only the client id and client secret, get authenticated and receive an access token back, then the app can use the access token to obtain the application's data. There is no regular user involved and the data belongs to the app. This is the same concept as your application connects to the database with a user name and user password belong to the application. The user uses the application without any knowledge of backend database accesses.
There are so many OAuth2 servers that support "code" grant type such as Google, Facebook, Github, but I have not found anyone that supports client credentials. Google asks me to set a service account, it is not the same as client credentials. Does anyone know an OAuth2 server that I use to test my client credential grant code? Thanks.

Keycloak has support for client credentials as authentication for the token endpoint.
https://www.keycloak.org/docs/latest/authorization_services/#_authentication_methods

Related

Client Credentials grant with Keycloak as an identity broker for Azure AD

I am trying to use client credentials grant for a back-end service using Keycloak as an identity broker for Azure AD. I also need to store access token from external IdP in Keycloak to retrieve group information from MS Graph API. I have this use case working for a confidential client using authorization code flow but I can't get it to work with client credentials grant.
I have created a "confidential" client in Keycloak with "Service Accounts Enabled" enabled. I have a also created an application in Azure AD with client credentials grant enabled and created a external Identity Provider in Keycloak.
I get the access token from Keycloak after authenticating using client_id and client_secret but when I try to retrieve external IdP access token from Keycloak endpoint, I get an error message that says, "User [GUID] is not associated with identity provider". I'd appreciate any suggestions or feedback.
Thank you Sventorben Posting your suggestions as answer to help other community members.
Though is grant on client credential from both side Azure AD and Keycloak it is not possible to store the access token from Azure AD in Keycloak and later retrieve it from Keycloak to make requests to Graph API.
The client credentials grant type is used by clients to obtain an access token. This is totally outside of the context of a user. Keycloak will not forward or redirect requests to AD in this case. Hence, there will never be an AD token. If you need client credentials grant issuing a token from AD, you will need to make the request to AD directly.
From the below document it seems Keyclock is broker it should never send the original access token which is receive from Azure AD to access the Graph API. Only you can read the token using enable StoredTokens Readable switch.
Refence: https://wjw465150.gitbooks.io/keycloakdocumentation/content/server_admin/topics/identity-broker/tokens.html

Can I use OAuth for authentication for trusted client (mobile app)?

I know how OAuth2 and OpenID Connect works. But there is still some confusion bothering me.
We develop our own Auth Server, service API and mobile app. So, the client app is trusted and we use "password" grant type. The app user repository follows the same user database in auth server.
Our customers login to the app by username/password. The app then submits the user credential to the Auth Server token endpoint, which will return the (bearer) access token and ID token (JWT) to the client.
The ID token contains basic user information so that the app can greet user like "Welcome Tony Stark!".
The access token can be used to access API (e.g. update user profile).
OAuth by design is not a tool for authentication. Ref: https://www.scottbrady91.com/OAuth/OAuth-is-Not-Authentication
My questions are
1) Do we need to verify the signature of the ID token if the client only is only interested to get the user information? Also note that the ID token is coming from the token endpoint via https connection.
2) Let's forget about the ID token. Can we treat the user has passed the authentication check (i.e. login success) if the client obtains an access token from the Auth Server? This flow is very similar to simple password login without OAuth.
3) The client can access protected APIs with the access token. Without access token, the client can only invoke some public APIs. Is it equivalent to what can be done with and without login? It seems the access token can be treated as "login session cookie".
4) There is no 3rd party involvement in my case. Everything (client, auth server, service API) is developed and owned by the same organization. Does it still make sense to use OAuth?
Typically a mobile app is considered a public client. Unless you're limiting who has access to the mobile app, it can't be considered trusted as someone could mess with the app outside of your control even if you developed it.
Also, the resource credentials grant type is generally not a good idea.
One thing is that the OpenID Connect spec requires authorization code, id token, or a hybrid flow:
Authentication can follow one of three paths: the Authorization Code
Flow (response_type=code), the Implicit Flow (response_type=id_token
token or response_type=id_token), or the Hybrid Flow (using other
Response Type values defined in OAuth 2.0 Multiple Response Type
Encoding Practices [OAuth.Responses]).
Some other reasons:
Why the Resource Owner Password Credentials Grant Type is not Authentication nor Suitable for Modern Applications
The OpenID Connect RFC says you MUST verify the ID token:
When using the Implicit Flow, the contents of the ID Token MUST be validated in the same manner as for the Authorization Code Flow, as defined in Section 3.1.3.7, with the exception of the differences specified in this section.
Although, you may qualify for this exception from 3.1.3.7 if using TLS:
If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature. The Client MUST validate the signature of all other ID Tokens according to JWS [JWS] using the algorithm specified in the JWT alg Header Parameter. The Client MUST use the keys provided by the Issuer.
If you're able to trust the client, and the user/pass check you've implemented, then you should be able to trust that an access token has been granted to an authenticated identity according to the OAuth 2.0 spec.
The access token in OAuth 2.0 also contains scopes and should limit what can be done with that access token. A login without OAuth doesn't necessarily.
It's a good idea to use OAuth to protect the credentials of the resource owner. If you were to use the resource owner credentials grant type, this still provides some benefits as the user could enter the password only when the client doesn't have a valid access token, ie, the user can enter her password once for an access token and validate the user using that instead of entering the password again or storing it somewhere.
Even though this grant type requires direct client access to the
resource owner credentials, the resource owner credentials are used
for a single request and are exchanged for an access token. This
grant type can eliminate the need for the client to store the
resource owner credentials for future use, by exchanging the
credentials with a long-lived access token or refresh token.
OAuth 2.0 RFC6749
1) Do we need to verify the signature of the ID token if the client
only is only interested to get the user information? Also note that
the ID token is coming from the token endpoint via https connection.
YES.
2) Let's forget about the ID token. Can we treat the user has passed
the authentication check (i.e. login success) if the client obtains an
access token from the Auth Server? This flow is very similar to simple
password login without OAuth.
If I understand the premise. Yes..There is no requirement for using the ID Token.
3) The client can access protected APIs with the access token. Without
access token, the client can only invoke some public APIs. Is it
equivalent to what can be done with and without login? It seems the
access token can be treated as "login session cookie".
The access token is a access (like a key) that for the OAuth Client to use that was delegated permissions from the resource owner.
4) There is no 3rd party involvement in my case. Everything (client,
auth server, service API) is developed and owned by the same
organization. Does it still make sense to use OAuth?
Yes. OAuth and OpenID Connect are used by many, many organizations and is a test solution.
You should not try to re-invent the "wheel". Use known trusted libraries for Authentication, Authorization and cryptographic operations. OpenID Connect has some certified Implementations

OAuth2 Password Grant vs OpenID Connect

I've been reading about OAuth and OpenID Connect extensively, but this question is specifically about the OAuth2 Resource Owner Password Grant (aka OAuth2 Resource owner credentials Grant, aka OAuth2 Password Grant)
Some resources (like the book "OAuth2 in Action" by Justin Richer) says not to use OAuth2 Resource Owner Password Grant for authentication - see section 6.1.3 in the book.
Other good resources like the following all say we can use the OAuth2 Resource Owner Password Grant to essentially authenticate users via trusted apps:
https://www.oauth.com/oauth2-servers/access-tokens/password-grant/
https://stormpath.com/blog/the-ultimate-guide-to-mobile-api-security
https://www.youtube.com/watch?v=FNz0Lupp8HM&index=60&list=PLyUlngzGzkztgTizxM6_zqiw8sRj7vBm0
https://docs.apigee.com/api-services/content/implementing-password-grant-type
https://oauth2.thephpleague.com/authorization-server/which-grant/
https://aaronparecki.com/oauth-2-simplified/#others
But I'm having a hard time understanding why we shouldn't use the OAuth2 Resource Owner Password Grant as essentially proof of a successful authentication?
My understanding of Resource Owner Password Grant flow is that a username and password is provided by the end user to the trusted client (my native app), which then forwards it to my API's OAuth server and exchanges it for an access token (and optional refresh token) that it can use for the rest of the authenticated API endpoints. The native app doesn't save the username/password, but instead relies on the short-lived access token and the longer-lived refresh token (to get fresh access tokens when they expire).
Why would I even need OpenID Connect? Why can't I just use OAuth2 Resource Owner Password Grant as an authentication mechanism?
Both the native app and the API are developed by the same person (me).
Any explanations would be welcome. Thank you.
If both the server and the client application are yours, you may use Resource Owner Password Credentials flow to get access tokens.
If the server is yours but client applications are not yours (= if client applications are developed by third-party vendors), your server should not allow client applications to use Resource Owner Password Credentials flow. It's because Resource Owner Password Credentials flow cannot prevent third-party client applications from stealing end-users' passwords.
The specification of OpenID Connect does not describe how an OpenID provider should authenticate end-users. Instead, the specification describes how an OpenID provider should generate ID tokens. Because an ID token contains a signature generated by the OpenID provider, client applications that receive the ID token can verify that the ID token has been really signed by the OpenID provider.
That is, OpenID Connect is a specification as to how to make the result of end-user authentication be verifiable. It's not a specification as to how to authenticate end-users.
The resource owner credentials grant is of the higher risk then any other grants and defeats the purpose of the protocol, which aims to hide user credentials from the client application.
In the case of native app - you are right, its possible to analyze your app and retrieve the consumer key from it. Also I can imagine someone creates an app similar to yours, and fishes user's password out of it, and executes other potentially malicious actions without users noticing.
I suggest you read the specifications of OAuth2 and OpenID Connect.
Why should you NOT use the resource owner password grant (from OAuth2 spec):
The resource owner password credentials grant type is often used for
legacy or migration reasons. It reduces the overall risk of storing
usernames and passwords by the client but does not eliminate the need
to expose highly privileged credentials to the client.
This grant type carries a higher risk than other grant types because
it maintains the password anti-pattern this protocol seeks to avoid.
The client could abuse the password, or the password could
unintentionally be disclosed to an attacker (e.g., via log files or
other records kept by the client).
Additionally, because the resource owner does not have control over
the authorization process (the resource owner's involvement ends when
it hands over its credentials to the client), the client can obtain
access tokens with a broader scope than desired by the resource
owner. The authorization server should consider the scope and
lifetime of access tokens issued via this grant type.
The authorization server and client SHOULD minimize use of this grant
type and utilize other grant types whenever possible.
OAuth 2.0, regardless of the grant type, is not an authentication protocol.
OpenID Connect is an Authentication Protocol built on top of OAuth 2.0
These are some references (Several are from folks that wrote the OAuth 2.0 and/or OpenID Connect):
http://www.thread-safe.com/2012/01/problem-with-oauth-for-authentication.html
https://twitter.com/ve7jtb/status/740650395735871488
https://nat.sakimura.org/2013/07/05/identity-authentication-oauth-openid-connect/
http://ldapwiki.com/wiki/OAuth%202.0%20NOT%20an%20Authentication%20protocol

WSO2 Identity Server: How to authenticate User?

I am using in-memory DB for storing user details in WSO2 Identity server. I create couple of users via UI and now I want to authenticate those user using some external application.
Is there any available WSO2 service which takes User credentials and authenticate based on the details provided? I saw few articles where they mainly talking about User Stores. But there, I think, they directly connect to DB to compare the credentials.
There are multiple ways to authenticate a user from Identity Server. Easiest way is that you can call the admin service (SOAP service) for authentication (RemoteUserStoreManagerService/authenticate). Or you can create a OAuth application inside the IS and use resource owner grant type to pass the credentials and authenticate.
You can find admin service related information from here [1] and password grant related information from here [2]
Is there any available WSO2 service which takes User credentials and
authenticate based on the details provided?
I believe we've misused the Token API service ( /token with password OAuth profile) to request an OAuth code and the WSO2IS effectviely validates the user's credentials.
I suggest your application would stick to some authentication and authorization standards supported by the WSO2IS, such as OAuth 2.0 or SAML.

How to start with OAuth Client Credentials to protect WebApi using OWIN Oauth?

I am a newbie to OAuth 2.0.
I have fairly read the OAuth 2.0 doc and I saw there are four types of methods for obtaining Authorization.
Types of obtaining authorization:
1.Implicit Grant
2.Resource Owner Password Credentials Grant
3.Client Credentials Grant
4.Authorization Code Grant
In my case, I have Client application, Resource owner, Resource server and Authorization server.
Resource server is a website where Resource owner registers with his/her credentials.
Client application is a third party website who registers into resource server and gets the Client application credentials for accessing it in future.
Authorization server checks the client credentials from client app and grants access token to the client app.
Let us consider, resource server as "www.serversite.com", authorization server as "www.authserver.com" and client application as "www.clientapp.com".
Flow:
Step 1: Also make an assumption that www.serversite.com as a payment gateway site and the client has to integrate "www.serversite.com" into "www.clientapp.com" for creating, executing and refunding payments.
Step 2: So the client "www.clientapp.com" creates an app in server "www.serversite.com" and gets API credentials.
Step 3: Using these API credentials, the client "www.clientapp.com" makes an access token request to the auth server "www.authserver.com".
Step 4: If the API credentials from client app are valid then the auth server grants an access token.
step 5: With this access token, client app request the resource server for further operations like creating payments as well as executing payments.
My questions:
I am using ASP.NET Web API for authorization server and using OWIN.OAuth for generating access token, refresh token, authorization and all the stuffs needed to authorize the client app.
But, in this link (OWIN OAuth 2.0 Authorization Server), I found that, the web api authorize the client app using "Resource Owner Password Credentials Grant" and the sample provided for implementing Owin.OAuth in web api is great, but I have lot of confusions roaming in my mind.
Which way of obtaining authorization is suitable for my process?
(Client Credentials flow or Resource Owner Password Credentials flow)
How to implement Client Credentials Grant type using ASP.NET Web
API(OWIN OAuth)?
Also provide some samples or links that may be helpful for me?
Thanks in advance.
Theres an example of how to get started on the asp.net website, specifically here:
http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server
I quote:
private Task GrantClientCredentails(OAuthGrantClientCredentialsContext context)
{
var identity = new ClaimsIdentity(new GenericIdentity(
context.ClientId, OAuthDefaults.AuthenticationType),
context.Scope.Select(x => new Claim("urn:oauth:scope", x))
);
context.Validated(identity);
return Task.FromResult(0);
}
Obviously you will need to go ahead and verify the actual client id / secret exist perhaps in a local database sometwhere before you go ahead and set the context to validated.
In terms of deciding which flow to use, you need to ask yourself, if the application is requesting access to your APIs on behalf of an actual user, then you need to use Resource Owner, however if the application itself needs access then Client Credentials is the way to go.
Generally speaking though, most implementations use Authorisation Code Flow, so if you can form a security stand point, get the users redirected to a page you host to take their credentials, opposed to sending them over the wire via Resource Owner Flow.