OAuth Auth Code Flow and SSO Initiated by API Provider - oauth-2.0

For this flow, the user (resource owner) starts in the UI of the API Provider (resource server). The aim is to transfer the user to an oauth client UI where the client app will be able to call APIs in the originating resource server. Note the client app is likely to be closely affiliated with the API Provider (e.g. a cloud service that has the same owner as the API Provider). An option is to send the user to the client which then initiates the usual auth code flow process, but it seems that this could be streamlined by just redirecting to the redirect_uri from the resource server to begin with. Probably best shown by a comparison of the two flow:
Standard OIDC OAuth SSO-type flow:
1) User in client UI.
2) Client directs user to API Provider (auth server).
3) User log-in in to auth server.
4) Authorize client app (/authorize).
5) Redirect to client providing auth code to redirect_uri for client.
6) Client uses auth code to obtain access_token and id_token (/token).
Abbreviated flow:
1) User is in API Provider UI.
2) User does activity which requires handoff to client.
3) Authorize client app (/authorize).
3) Redirect to client providing auth code to redirect_uri for client.
5) Client uses auth code to obtain access_token and id_token. (/token)
Note steps 3 - 5 in abbreviated flow correspond to steps 4 - 6 in standard flow. Since the user starts in the API+Identity Provider, it seems unnecessary to send user to third party so that they can start the flow.
I am wondering what pitfalls there are with the abbreviated flow - for example, there is no state parameter from the client, but the process is started by the API Provider, so I am not sure that there needs to be. Is there a more suitable flow to use than the abbreviated flow described above to hand off to a client app?

Related

Using JWT to authorize REST API requests after SAML Authentication

I'm struggling theese days on the possible way to configure an Authentication + authorization system to consume a REST API from a mobile application.
Scenario:
We've developed 3 independent portals for a big customer that serves several users.
To enable a SSO for the 3 portals we've implemented a SAML authentication system using SimpleSAMLphp.
Every portal has a service provider and they make assertion requests against a central IdP.
The IdP checks username and password against a database where passwords are hashed and stored during registration.
After the login, the authorization on the portals is handled by the session on the server, and so far everything was fine.
Now the customer asked us to develop a mobile application that will require the users to login and access several of their protected resources collected during the usage of the 3 portals.
We've decided to develop a frontend application using ionic that will consume a REST API made in node.js that will serve all the data (both protected and unprotected resources).
Now here comes the question: to authorize access to protected resources on the Api we'd like to use JWT to easily achieve a stateless system.
The doubt is how to perform the authentication? We've the opportunity to check the credentials directly against the database skipping the SAML process, otherwise we've to implement a solution where the SSO IdP acts as authentication provider and then when an attempt is successful the API app will get the response from the idp and then issue a signed jwt to the consumer client. Is this second way a common implementation? Is it possible?
What path do you suggest to follow? The first could be very easy to achieve, but since we're using html+js for the app's frontend, if we decide to use the second solution probably in the near future we could recycle some code from the app to modernize some functions on the web portals, maintaining the jwt pattern and consuming the new Api also on the web.
I believe that in this case will be easier to ask a token to the new api using someway the logged in user's data already in the session of the portal. Sounds possible?
I hope that everything was clear, any help will be appreciated!
Thanks
The key goal here is to code your apps in the best way, via
the latest security standards (OAuth 2.0 and Open Id Connect).
SAML is an outdated protocol that is not web / mobile / API friendly, and does not fit with modern coding models.
Sounds like you want to do OAuth but you do not have an OAuth Authorization Server, which is a key part of the solution. If you could migrate to one you would have the best future options for your apps.
OPTION 1
Use the most standard and simple option - but users have to login with a new login screen + credentials:
Mobile or Web UI uses Authorization Flow (PKCE) and redirects to an Authorization Server to sign the user in
Mobile or Web UI receives an access token after login that can be sent to the API
Access token format is most commonly a JWT that the API can validate and identify the user from
The API is not involved in the login or token issuing processes
OPTION 2
Extend option 1 to federate to your SAML Identity Provider - enables users to login in the existing way:
The Authorization Server is configured to trust your SAML based identity provider and to redirect to it during logins
The SAML idp presents a login screen and then posts a SAML token to the Authorization Server
The Authorization Server issues OAuth based tokens based on the SAML token details
OPTION 3
Use a bridging solution (not really recommended but sometimes worth considering if you have no proper authorization server - at least it gets your apps using OAuth tokens):
Mobile or Web UI uses Resource Owner Password Grant and sends credentials to a new OAuth endpoint that you develop
OAuth endpoint provides a /oauth/token endpoint to receive the request
OAuth endpoint checks the credentials against the database - or translates to a SAML request that is forwarded to the IDP
OAuth endpoint does its own issuing of JWT access tokens via a third party library (if credentials are valid)
Web or Mobile UI sends JWT access token to API
API validates received JWT access token

Open ID Token vs Oauth Token

I am new to OAuth and OpenId, and after reading multiple pages and information I still do not feel confident at all.
My goal would be to create an iOS Application that communicates with my BE. I need the iOS app to authenticate the user to access their resources.
Reading about OAuth, the solution seems to be straight forward. Just use the Authorization Code Flow with PKCE to make the App have an Access Token. This way I am authorizing my iOS app to access user's data. When the iOS app calls https://example.org/user with the access token, the resource service (my BE server) can get the access token and call the introspection API to know to which user the access token is bound to, and return the correct user data. Since authorization needs authentication to be made in the first place, having the access token would mean that the user is (or at least was) authenticated.
First thing that confuses me: According to the OAuth specs, OAuth is not an authentication protocol, but still the protocol authenticates the user using the user's credentials. Why is OAuth asking the user for credentials, instead of relying on another protocol/flow for user authentication? Such protocol would just acknowledge to OAuth that the authentication was successful.
This first issue made me start reading about Open ID Connect specification and the ID Token. This token would be received by the iOS app. What is the iOS App supposed to do with it? I can already get the user information calling the /user endpoint. How would this ID Token be an advantage?
tldr
Access token (OAuth 2.0) - authorize against OAuth protected
endpoints.
ID Token (OIDC) - authentiation by client application.
Authorization server authentication - It's there to detect
authenticity of end user involved in both protocols (pseudo
authentication from client application perspective)
OAuth is not an authentication protocol, but still the protocol contain a step to authenticate the user using the user's credentials
Correct, OAuth is not an authentication protocol. It is for authorization, which means identifying there are correct access grants to access a protected resource (protected resource ? ex:- An API, A photo stored in a backend).
So why you see end user login dialog ? Well that is the job of authorization server. It authenticate end user to be known by it and then issue the access token to client (client == in simple terms the application which end user uses). So yes there is an authenitcation happening, but this is not applicable to your client application or protected endpoint. One can define this as an pseudo authentication.
OpenID Connect - For authentication of client application
In the original RFC (RFC-6749), OAuth 2.0 was defined as a framework. OpenID Connect was an extension that built on this framework. What it provide ? Well as you found out, it introduce the ID Token. And ID token is issued by authorization server to be consumed by your client application. It contains end user identity information in JWT format. By validating integrity of this token, your client application can authenticate the end user. And access token ? That's there to used against protected endpoint. It doesn't say anything about end user to client.

Need an API design pattern where I can expose the same api to background process and end clients

Our apis are being consumed by 3rd party deamon applications as well as client applications. For third party deamon application we can expose the api via the client credential oauth flow and for the client application(S) we use the implicit grant outh flow.
The challenge we are facing is that in case of the implicit grant flow the user details are fetched from the ACCESS TOKEN. But when the same api is used for the client credential flow the user details can not be fetched from the ACCESS token as it has only application specific details.
What is the the best api design approach to handle the above challenge ?
Do I need two set of api(s) one for integrating with client application and one for integrating with server application ?
Will the usage of any alternative oauth flow help ?
Refer to Authentication scenarios for Azure AD documentation, as you stated correctly user interaction is not possible with a daemon application, which requires the application to have its own identity. This type of application requests an access token by using its application identity and presenting its Application ID, credential (password or certificate), and application ID URI to Azure AD. After successful authentication, the daemon receives an access token from Azure AD, which is then used to call the web API.
The quintessential OAuth2 authorization code grant is the authorization grant that uses two separate endpoints. The authorization endpoint is used for the user interaction phase, which results in an authorization code. The token endpoint is then used by the client for exchanging the code for an access token, and often a refresh token as well. Web applications are required to present their own application credentials to the token endpoint, so that the authorization server can authenticate the client.
Hence, the recommended way is two have two version of api implemented with two different type of authentication based on your scenario.
Reference -
Daemon or server application to web API
Understanding the OAuth2 implicit grant flow in Azure Active Directory (AD)

oauth2 - how was user identified before OIDC?

Im a bit confused about oauth2 and OIDC.
So supposedly with OIDC we now get the id_token which uniquely identifies the user in the same oauth2 flow.
But my understanding is - oauth 2 came out earlier than OIDC and OIDC support is not universal even at this point.
So how do current APIs that use oauth2 (without OIDC) work?
Let's say there is a mobile app that needs to use some API.
Is the idea that after mobile app get's oauth2 access token -> they always have to hit some endpoint like /me using that access token which will then provide user id information? and thus the api has to track which access tokens have been given to each particular user?
Sry this question comes out like request for some trivia info - but Im really new to oauth2 & OIDC and just trying to understand and make sure im not missing anything....
OAuth 2.0 NOT an Authentication protocol.
OAuth 2.0 is more of a delegation protocol where the Resource Owner delegates certain permissions to a OAuth Client.
OIDC is an Authentication protocol built on top of OAuth 2.0.
OAuth 2.0 should be used where a user (Resource Owner) is delegating permissions to an Application (OAuth Client) to perform some action.
OIDC should be used where an an Application (OAuth Client) needs to some "Level of Assurance" that the user (Resource Owner) is who he says he is.
The Authentication is done by a Third-Party (Authorization Server). The id_token allows the Client to access information about the user that the Authorization Server knows about (and hopefully has performed some verification).
As jwilleke answered it, OAuth 2.0 is for authorization. OpenID Connect (OIDC) is built on OAuth 2.0 adds Authentication layer.
Basically, OAuth 2.0 delegate the client application to access a protected endpoint on-behalf of the resource owner. In simple words, end user authorise the application access a resource/service. In this process, application does not receive any detail about the end user so it cannot authenticate/detect(In OIDC, application receive the id token, which is self-sufficient enough to authenticate the end-user) end user.
Q : Is the idea that after mobile app get's oauth2 access token -> they always have to hit some endpoint like /me using that access token which will then provide user id information? and thus the api has to track which access tokens have been given to each particular user?
From OAuth 2.0 perspective, there is no end user information sharing. But the token issuing identity provider understand the tokens it issued. Internally it can map end user details, permissions and anything it requires to process it. With that, when the API (resource server) receive the access token, it can validate the token. Note that resource server and authorization could be the same or different. And these are implementation specific details. Alternatively one could use token introspection as defined in rfc7662 to detect validity of issues access tokens.
Example scenario
You have mobile app A. And it have the ability to use a service B (protected by Access tokens) which is exposed by service provider G. Assume there is a user Alex who have already registered at SP G so have access to service B and uses app A. And SP G have OAuth 2.0 implemented so service B accepts access tokens issued by SP G.
User Alex use App A and there is a functionality in the App A which need to consume service B. App A require authorisation from Alex to consume service B on-behalf of him/her. In doing so, there will be a user login process and at the end SP G issue access token to App A. Does it convey identity of Alex ? No it does not. But App A can now consume service B using access token it received. Service B fully understand and can validate access tokens issues by SP G. IMO This is OAuth 2.0 in nutshell.
p.s - Substitute known services like Google calendar, Google identity and your android app so that it make more sense.

When to use which OIDC/OAuth flow?

I'm immensly confused as to which OAUTH/OIDC flow to use when...
I've put together the following list to work through the options, and would appreciate someone correcting me if I'm getting it wrong. Thank you.
What I think I've understood so far is the following use cases:
A server-generated views web app (eg: ASP.NET or ASP.MVC based) that is refreshing on every request, and does not use AJAX to access authenticated APIs: use authorization code grant type flow.
A server-generated views web app (eg: ASP.MVC based) that is refreshing often, but does use AJAX to access authenticated APIs, and the server does not access 3rd parties APIs either as itself (the app) or on behalf of the user: use authorisation code grant type flow
server set session cookie to access APIs.
A server-generated views web app (eg: ASP.MVC based) that is refreshing often, but does use AJAX to access authenticated APIs, and the server does access 3rd parties APIs as itself (the app): use authorisation code grant type flow
server set session cookie to access APIs + use client credential grant type flow.
A client-side generated views web app (SPA), where the client invokes authenticated API endpoints on its source server, and the server does not invoke 3rd parties services as either itself (the app) or as the user: use implicit grant type flow, caching the authentication token in the user agent's sessionstorage, and passing the authentication_token* back on every request as a Bearer Token.
A client-side web app (SPA), where the client invokes authenticated API endpoints on its source server, and the server does invoke 3rd parties services as itself (the app): use implicit grant type flow, caching the authentication token in the user agent's sessionstorage, and passing the authentication_token back on every request as a Bearer Token, and use the client credential grant type flow*.
This probably is the most uncertain one: A client-side web app (SPA), where the client invokes authenticated API endpoints on its source server, and the server does invoke 3rd parties services as the the user: use implicit grant type flow, caching the authentication token in the user agent's sessionstorage, and passing the authentication_token back on every request as a Bearer Token, which the server can pass on to the 3rd party services (CHECK) to authenticate the user with. As the token is only encoded and signed, not encrypted, the token's claims can be read. Note: that may contain claims not intended for the 3rd party service.
Alternatively the flow might be:
The UI could precheck that the User is allowed to access the 3rd party service (eg: Order Flowers) and gray out the functionality to use the server api that will invoke the 3rd party service till the user has collected and stored a second authorisation token (but then how would the user agent pass that token back, if the call to the API was already using the authorisation header for its own bearer token?)

Resources