Consider the following distributed system that uses OAuth 2.0 for authorization and OpenID 2.0 for authentication.
Where
RS1, RS2 and RS3 are "Resource Servers" (aka three different REST APIs)
APP1 and APP2 are clients
AS is an "Authorization Server" for managing OAuth tokens
OPENID is an OpenID 2.0 provider.
APP2 uses RS1, which in turn is uses resources on RS2 and RS3. There is a trust between RS1, RS2, RS3, APP2, AS and OPENID as they are developed by the same company (but different teams). When a user access APP2 for the first time, APP2 is automatically authorized to access resources on RS1, RS2 and RS3 on behalf of the user.
APP1 uses resources in RS2, which in turn uses resources in RS3. APP1 is a third party website which is not trusted and a user needs to explicitly authorize APP1 to get access to resources on RS2 and RS3.
Most examples regarding OAuth 2.0 shows the communication between a single resource and authorization server and how to request, issue and manage the tokens.
How would one secure this environment using OAuth 2.0? For example, would APP2, RS1 and RS2 have their own client identifier and client secret (as they are all "clients" to another server)? If so, how would one issue access tokens for RS1 when it tries to access resources on RS2 and RS3 for the first time in the middle of another request (coming from APP2)?
I already have AS, OPENID, APP2 and RS1, which was developed using ASP.NET MVC 3, WCF 4 and DotNetOpenAuth 4. I'm trying to introduce RS2, RS3 and APP1 into the system but struggle to figure out how authorization between the resource servers and clients will work. Everything runs under IIS 7.5 and HTTPS.
I assume APP2 is a web app, since any other type of app can't be "trusted" as soon as it is downloaded to the client machine.
I think you're right on as far as authenticating your trusted apps to each other using client credentials. DotNetOpenAuth 4.0 beta doesn't yet support client credentials but that's hopefully coming in the next week or so.
In OAuth 2, client credentials would be built into your trusted clients. These credentials would be exchanged at runtime for refresh and access tokens that would be sent to the resource servers. You apply the access token to each outbound HTTP request using a DNOA API that will automatically renew any expired access tokens by another request to the authorization server.
Related
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
I have an Asp.Net Core 2.0 Web API running as a web app in Azure. My API is consumed by client applications which are windows service running on servers at various client sites. So, this is a "Daemon or Server Application to Web API" communications flow as described in Authentication Scenarios for Azure AD
I register the client application at each site as a separate unique app in Azure AD, obtain the ClientId and AppKey and send it to the respective site for their devs to use in their service to request a JTW access token from Azure AD to use in the authorization header when making an http request to my API.
This is all working just fine.
The question I have is this; is there any way, in this scenario, that I can identify which site is making the request? From what I understand, it doesn't seem like I can add custom claims to an OAuth2.0 access token, like can be added to an OIDC ID token.
If you register the apps yourself then you know all the client ids for each different site so your API could use the appid in the JWT access token (which is the client id) and cross reference it against a list of sites. Here is an example of a JWT token obtained using the client credentials grant type:
We have a web portail using some exposed API from a service desk application to create and list tickets. oAuth 2.0 is used to authenticate the requests through Google server. Below is the roles of the differents components :
Google oAuth 2.0 : Authentication server
Service Desk application : Resource server with exposed API
Client : Web portail
Which oAuth fow i have to use to authenticate the requests from the client to the resource server ? I think it's the client credentials.
How to check when the resource server receives a request that the request is authorized and can access the resource ? Currently, the resource server checks the access token provided with the request through the authorization server Google (using the API useremail endpoint), then, the resource server checks locally in a file if the client_id is declared.
Any help will be welcome
Thanks
If you want to keep the token at the web portal, you probably want to use the Implicit flow. The Resource Owner Password Credentials flow has some problems:
It requires a client password, which cannot be stored safely in a browser,
Your web portal gets the username and password (of a portal user), which is not good from the security standpoint
You cannot handle authorization of your own application (Service Desk) using Google access tokens, because they contain only Google-related scopes (for accessing Google services and resources). You can either do it locally - have some mapping between Google users and local roles or to have your own OAuth2 server with your own scopes that accepts Google authentication (for example KeyCloak).
I'd like to authenticate a legacy java (6) application against a node-js one currently secured using keycloak OIDC bearer only (both apps belonging to same realm).
I've been told to use keycloak-authz-client library resolving a keycloak OIDC JSON as below
{
"realm": "xxx",
"realm-public-key": "fnzejhbfbhafbazhfzafazbfgeuizrgyez...",
"bearer-only": true,
"auth-server-url": "http://xxx:80/auth",
"ssl-required": "external",
"resource": "resourceName"
}
However, the keycloak java client required java 8 and my current runtime is a jre6. Recompiling the lib including transitive dependencies does not looks like a good idea and I end up so using keycloak oauth2 REST endpoint.
As far as I know oauth2 I would go with a client_credentials flows exchanging a client secret against an access_token once at application initialization and refreshing / renewing when expired.
Coming to keycloak documentation :
Access Type
This defines the type of the OIDC client.
confidential
Confidential access type is for server-side clients that need to perform a browser login and require a client secret when they turn an
access code into an access token, (see Access Token Request in the
OAuth 2.0 spec for more details). This type should be used for
server-side applications. public
Public access type is for client-side clients that need to perform a browser login. With a client-side application there is no way to
keep a secret safe. Instead it is very important to restrict access by
configuring correct redirect URIs for the client. bearer-only
Bearer-only access type means that the application only allows bearer token requests. If this is turned on, this application cannot
participate in browser logins.
It seems that confidential access type is the one suitable for my needs (should be used for server-side applications) however I don't get how it is related to browser login (which is my mind is related to authenticating using third parties identity providers as facebook and co).
The confidential client settings also require a valid redirect uri the browser will redirect to after successful login or lagout. As the client I want to authenticate is an application I don't see the point.
Generally speaking I don't get the whole access type things. Is it related only to the client or to the resource owner also (Is my node.js application stuck to bearer-only as existing clients use this access type ? will it accept the bearer authentication using the access_token obtained with client_credentials flow ? I suppose it will).
Can someone clarify keycloak OIDC access type and where I went wrong if I did ?
What is the proper way to delegate access for my legacy application to some resources (not limited to a specific user ones) of another application using keycloak ?
You are mixing up the OAuth 2.0 concepts of Client Types and Grants. Those are different, albeit interconnected, concepts. The former refers to the application architecture, whereas the latter to the appropriate grant to handle a particular Authorization/Authentication use-case.
One chooses and combines those options; first one choses the client type (e.g., public, confidential), and then the grant (e.g., Authorization code flow). Both client types share some of the same grants, with the caviar that the confidential client will require also a client secret to be provided during the execution of the Authentication/Authorization grant.
From the Oauth 2.0 specification:
OAuth defines two client types, based on their ability to
authenticate securely with the authorization server (i.e., ability to
maintain the confidentiality of their client credentials):
confidential
Clients capable of maintaining the confidentiality of their
credentials (e.g., client implemented on a secure server with
restricted access to the client credentials), or capable of secure
client authentication using other means.
public
Clients incapable of maintaining the confidentiality of their
credentials (e.g., clients executing on the device used by the
resource owner, such as an installed native application or a web
browser-based application), and incapable of secure client
authentication via any other means.
As one can read the client type refers to the type of the application architecture. Why do you need those types? The answer is to add an extra layer of security.
Let us look at the example of the Authorization Code Grant. Typically the flow is as follows:
The user goes to an application;
The user gets redirect to the Keycloak login page;
The user authenticates itself;
Keycloak check the username and password, and if correct, sends back to the application an authorization code;
The application receives that code and calls Keycloak in order to exchange the code for tokens.
One of the "security issue" with that flow is that the exchange of code for token happens on the frontend channel which due to the nature of browsers it is susceptible to a hacker intercepting that code and exchange it for the tokens before the real application does it. There are ways of mitigating this but it is out of the scope of this question.
Now, If your application is a single-page application, then it cannot safely store a secret, therefore we have to use a public client type. However, if the application has a backend where the client secret can be safely stored, then we could use a confidential client.
So for the same flow (i.e., Authorization Code Grant), one can make it more secure by using a confidential client. This is because the application will now have to send to Keycloak a client secret as well, and this happens on the backend channel, which it is more secure than the frontend channel.
What is the proper way to delegate access for my legacy application to
some resources (not limited to a specific user ones) of another
application using keycloak ?
The proper grant is to use the so called Client Credential Grant:
4.4. Client Credentials Grant
The client can request an access token using only its client
credentials (or other supported means of authentication) when the
client is requesting access to the protected resources under its
control, or those of another resource owner that have been previously
arranged with the authorization server (the method of which is beyond
the scope of this specification).
Since this grant uses the client credentials (e.g., client secret) you can only use it if you have selected confidential as the client type.
We are already using CAS for single sign on for several web applications that we are hosting. Now we are going to deploy several HTTP/REST services in our network and those need authentication and authorization.
Would it be a good idea to combine CAS with OAuth ?
Users would still use CAS for SSO, but additionally login procedure would issue OAuth ticket that would be used to access REST services.
REST services can be protected via CAS proxy authn. Additionally, they can be integrated with OAuth. CAS provides both OAuth and OIDC protocol functionality as well.
That's certainly valid. OAuth 2.0 doesn't specify/dictate how the user (Resource Owner) is authenticated and CAS/SSO is fine for that. Effectively you'd be leveraging a CASified Authorization Server so that the Resource Owner authenticates with CAS to the Authorization Server, which is "just" an application to the CAS SSO system. The Authorization Server would then issue an access token down to the Client so that the Client can use that access token to access the protected resources i.e. the REST services.