How do I set up API authentication for M2M (Machine to Machine) in OneLogin? - onelogin

I would like to set up API authentication for M2M (Machine to Machine) in OneLogin. How can I set up API that is used by multiple systems?
I tried the following two patterns from the official site, but I am not sure which one I should choose.
I would like to know how to implement each pattern.
Also, in which case should I choose which pattern?
Pattern 1
Obtain a token with "Client Credentials Grant" on the system you are connecting from, and perform "Validate a Token" on the system on the authentication side.
This pattern requires that an application be created for each system on the OneLogin administration site, but I don't know how to determine which system it is on the authentication side.
URLs for "Client Credentials Grant" and "Validate a Token"
https://developers.onelogin.com/openid-connect/api/client-credentials-grant
https://developers.onelogin.com/openid-connect/api/validate-token
Pattern 2
I understand that the "Generate Tokens" will be used to obtain a token on the system from which I am connecting, but I do not know how to implement this on the authentication side of the system.
URL of "Generate Tokens
https://developers.onelogin.com/api-docs/2/oauth20-tokens/generate-tokens-2

Related

Signing into my Gitlab CE installation with my app's login

I have a nodejs webapp with many users with a custom login process. I would like gitlab to accept that authentication and not force users to create a new app. What is the best way to accomplish this?
I would go for OAuth 2.0 Single Sign On (SSO). Below you can find the architecture diagram taken from here. As you can see the client is redirected to log in in the OAuth2 provider to get a valid token for authentication. The OAuth2 server must be configured for the application requesting access including the secret, the client id and the callback URL.
You can configure GitLab CE to sign in with almost any OAuth2 provider. Only be careful with the limitations:
It can only be used for Single Sign on, and will not provide any other access granted by any OAuth provider (importing projects or users, etc)
It only supports the Authorization Grant flow (most common for client-server applications, like GitLab)
It is not able to fetch user information from more than one URL
It has not been tested with user information formats other than JSON
You also need to configure your node js web application as an OAuth2 server. There are npm availables with the source code here.
Recommendation
I would install some open source Identity Management to separate the user management from your webapp, provides better integration with other third parties and forget about encryption and other stuff you need to take care in your webapp. There are multiple options such as KeyCloak for instance.
You have to define a dedicated user , and use the private_token of this user to login for ALL users that will use your application.
The restricition would imply all users will have the same rights ....
The other solution is to use the Private Token of the user at login. In this case , only the rights of these particular users will be used.

Can this OAuth2 Native app flow be considered secure?

I have an OpenID Connect provider built with IdentityServer4 and ASP.NET Identity, running on let's say: login.example.com.
I have a SPA application running on let's say spa.example.com, that already uses my OpenID Connect provider to authenticate users through login.example.com and authorize them to access the SPA.
I have a mobile app (native on both platforms) that is using a custom authentication system at the moment.
I thought it would be nice to get rid of the custom auth system, and instead allow my users to log-in with the same account they use on the SPA, by using my OpenID provider.
So I started by looking on the OpenID connect website and also re-reading the RFC6749, after a few google searches I realized that was a common problem and I found RFC8252 (OAuth2 for Native clients), also Client Dynamic Registration (RFC7591) and PKCE (RFC7636).
I scratched my head about the fact that it was no longer possible to store any kind of "secret" on the client/third-party (the native apps) as it could become compromised.
I disscussed the topic with some co-workers and we came out with the following set-up:
Associate a domain let's say app.example.com to my mobile app by using Apple Universal Links and Android App Links.
Use an AuthenticationCode flow for both clients and enforce them to use PKCE.
Use a redirect_uri on the app associated domain say: https://app.example.com/openid
Make the user always consent to log-in into the application after log-in, because neither iOS or Android would bring back the application by doing an automatic redirect, it has to be the user who manually clicks the universal/app link every time.
I used AppAuth library on both apps and everything is working just fine right now on test, but I'm wondering:
Do you think this is a secure way to prevent that anyone with the right skills could impersonate my apps or by any other means get unauthorized access to my APIs? What is the current best practice on achieving this?
Is there any way to avoid having the user to always "consent" (having them to actually tap the universal/app link).
I also noted that Facebook uses their application as a kind of authorization server itself, so when I tap "sing-in with facebook" on an application I get to a facebook page that asks me if I would like to" launch the application to perform log-in". I would like to know how can I achieve something like this, to allow my users login to the SPA on a phone by using my application if installed, as facebook does with theirs.
I thought it would be nice to get rid of the custom auth system, and instead allow my users to log-in with the same account they use on the SPA, by using my OpenID provider.
This is what OAuth 2.0 and OpenID Connect provides you. The ability to use single user identity among different services. So this is the correct approach .!
it was no longer possible to store any kind of "secret" on the client/third-party (the native apps) as it could become compromised
Correct. From OAuth 2.0 specification perspective, these are called public clients. They are not recommended to have client secrets associated to them. Instead, authorization code, application ID and Redirect URL is used to validate token request in identity provider. This makes authorization code a valuable secret.!
Associate a domain let's say app.example.com to my mobile app by using Apple Universal Links and Android App Links.
Not a mobile expert. But yes, custom URL domains are the way to handle redirect for OAuth and OpenID Connect.
Also usage of PKCE is the correct approach. Hence redirect occur in the browser (user agent) there can be malicious parties which can obtain the authorization code. PKCE avoid this by introducing a secret that will not get exposed to user agent (browser). Secret is only used in token request (direct HTTP communication) thus is secure.
Q1
Using authorization code flow with PKCE is a standard best practice recommended by OAuth specifications. This is valid for OpenID Connect as well (hence it's built on OAuth 2.0)
One thing to note is that, if you believe PKCE secret can be exploited, then it literally means device is compromised. Think about extracting secret from OS memory. that means system is compromised (virus/ keylogger or what ever we call them). In such case end user and your application has more things to be worried about.
Also, I believe this is for a business application. If that's the case your clients will definitely have security best practice guide for their devices. For example installation of virus guards and restrictions of application installation. To prevent attacks mentioned above, we will have to rely on such security establishments. OAuth 2.0 alone is not secure .! Thats's why there are best practice guides(RFC68129) and policies.
Q2
Not clear on this. Consent page is presented from Identity Provider. So it will be a configuration of that system.
Q3
Well, Identity Provider can maintain a SSO session in the browser. Login page is present on that browser. So most of the time, if app uses the same browser, users should be able to use SPA without a login.
The threat here comes from someone actually installing a malicious app on their device that could indeed impersonate your app. PKCE prevents another app from intercepting legitimate sign in requests initiated from your app so the standard approach is about as safe as you can make it. Forcing the user to sign in/consent every time should help a bit to make them take note of what is going on.
From a UX PoV I think it makes a lot of sense to minimize the occasions when the browser-based sign in flow is used. I'd leverage the security features of the platform (e.g. secure enclave on iOS) and keep a refresh token in there once the user has signed in interactively and then they can sign in using their PIN, finger print or face etc.

Token based security strategy and considerations

I'm working on a security setup suitable for the following client/server scenario, and I'm having a couple of questions/considerations that I'd like to share with you.
Situation:
I have a number clients on different platforms:
HTML-client (single page apps (SPAs) using jQuery/AJAX)
Android-app
Silverlight client
Windows client
Windows Mobile client
The large majority of the corresponding server components are based on .NET WCF using REST (but for some backends, I'm using other protocols).
I've found the open source project IdentityServer v2 from ThinkTecture to be a nice and flexible security token service (STS) for my solution. It supports a number of token types, protocols and is highly extendable and has a self contained Identity Provider (IdP) based on ASP.NET Membership database if needed.
The basic flow for clients using usernames/passwords is as follows:
The client makes an unauthorized HTTP call to a ressource (that requires authorized access) on its server
As the client is not yet authenticated, the server returns a HTTP 401 (unauthorized) providing an address to the STS in an HTTP Location header (see note on this below)
The client submits its credentials to the STS in a HTTP Basic Auth header
The STS returns a JWT token containing all relevant user claims
The client now repeats its initial request from step 1 including the JWT token in the HTTP Auth Bearer header
The server validates the token, as it originates from a trusted STS source, and returns the requested ressource
I know that step #2 is a bit unorthodox in combining the HTTP 401 error message with a HTTP Location header normally associated with the HTTP 3xx status codes. I need the 401 status code because of my jQuery/AJAX clients which handle the 302 redirect message automatically without any chance to interscept the redirect.
Now, the system needs to use an external IdP. The "internal" STS is customized to forward auth requests to the external IdP handling transformation of claims from the external IdP format to the internal format. One catch with this is that it implies the "password anti-pattern", but for now all systems are interal and trustworthly.
Could WS Federation be my friend?
The above basic flow applies to at all clients, browser based or not. But for specifically browser clients, I've been looking into a federated security scenario, having the resulting IdP/STS to provide a login mechanism for the clients. The STS that I use (IdentityServer) can be configured to be used in conjunction with a WS-Federation compliant STS. Thereby tokens are automatically transferred to the target token format (in my case for instance from the external STS's SAML token to the internal JWT token).
With this I can have some sort of a SSO mechanism.
Now my questions:
Is my described basic security flow optimal?
Is WS-Federation only applicable for browser clients?
If not, how can it be used with for instance my android clients?
In WS-Federation with more STSs, how is the communication flow between: client - internal STS - external STS (in terms of HTTP communication, cookies and stuff).
I don't think what you describe is WS-Fed. WS-Fed never involves 401 and never involves authentication headers.
WS-Fed has two versions, passive and active.
Passive is for browsers. It consist in 302 to the identity provider which in turn POSTs the SAML token back to the caller. The authenticaiton is then supported by cookies.
Active is for active clients (applications). It consist in a SOAP response that instructs the caller to go to the identity provider for the token. The SOAP response from the identity provider contains a token which is then supplied to the service.
What I believe is that the active scenario is quite complicated if your client doesn't support the WCF federation authentication binding (wsTrustFeb2005). You'd have to implement the flow on your own.
What I'd like to recommend instead would be the OAuth2 flow. OAuth2 has 4 different flows, of which two correspond to WS-Federation's active and passive: authorization code flow is for browser-based apps and the implicit flow is for desktop/mobile applications.
http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified#authorization
OAuth2 integrates easily with WebAPI services and there is a great support for it in the DotnetOpenAuth library.
This and other authentication/authorization options are described in great detail in the Pro ASP.NET WebAPI Security book
http://www.amazon.com/Pro-ASP-NET-Web-API-Security/dp/1430257822
Even if you are not planning to build your backend around WebAPIs (but rather RESTful WCF as you mention), the book will give you necessary background on OAuth2.
On the other hand, if you still insist on WS-Federation, this free e-book describes both active and passive scenarios:
http://msdn.microsoft.com/en-us/library/ff423674.aspx

What's the right OAuth 2.0 flow for a mobile app

I am trying to implement delegated authorization in a Web API for mobile apps using OAuth 2.0. According to specification, the implicit grant flow does not support refresh tokens, which means once an access token is granted for an specific period of time, the user must grant permissions to the app again once the token expires or it is revoked.
I guess this is a good scenario for some javascript code running on a browser as it is mentioned in the specification. I am trying to minimize the times the user must grant permissions to the app to obtain a token, so it looks like the Authorization Code flow is a good option as it supports refresh tokens.
However, this flow seems to rely heavily on a web browser for performing the redirections. I am wondering if this flow is still a good option for a mobile app if a embedded web browser is used. Or should I go with the implicit flow ?
Clarification: Mobile App = Native App
As stated in other comments and a few sources online, implicit seems like a natural fit for mobile apps, however the best solution is not always clear cut (and in fact implicit is not recommended for reasons discussed below).
Native App OAuth2 Best Practises
Whatever approach you choose (there are a few trade offs to consider), you should pay attention to the best practices as outlined here for Native Apps using OAuth2: https://www.rfc-editor.org/rfc/rfc8252
Consider the following options
Implicit
Should I use implicit?
To quote from Section 8.2 https://www.rfc-editor.org/rfc/rfc8252#section-8.2
The OAuth 2.0 implicit grant authorization flow (defined in Section 4.2 of OAuth 2.0 [RFC6749]) generally works with the practice of performing the authorization request in the browser and receiving the authorization response via URI-based inter-app communication.
However, as the implicit flow cannot be protected by PKCE [RFC7636] (which is required in Section 8.1), the use of the Implicit Flow with native apps is NOT RECOMMENDED.
Access tokens granted via the implicit flow also cannot be refreshed without user interaction, making the authorization code grant flow --
which can issue refresh tokens -- the more practical option for native app authorizations that require refreshing of access tokens.
Authorization Code
If you do go with Authorization Code, then one approach would be to proxy through your own web server component which enriches the token requests with the client secret to avoid storing it on the distributed app on devices.
Excerpt below from: https://dev.fitbit.com/docs/oauth2/
The Authorization Code Grant flow is recommended for applications that
have a web service. This flow requires server-to-server communication
using an application's client secret.
Note: Never put your client secret in distributed code, such as apps
downloaded through an app store or client-side JavaScript.
Applications that do not have a web service should use the Implicit
Grant flow.
Conclusion
The final decision should factor in your desired user experience but also your appetite for risk after doing a proper risk assessment of your shortlisted approaches and better understanding the implications.
A great read is here https://auth0.com/blog/oauth-2-best-practices-for-native-apps/
Another one is https://www.oauth.com/oauth2-servers/oauth-native-apps/ which states
The current industry best practice is to use the Authorization Flow
while omitting the client secret, and to use an external user agent to
complete the flow. An external user agent is typically the device’s
native browser, (with a separate security domain from the native app,)
so that the app cannot access the cookie storage or inspect or modify
the page content inside the browser.
PKCE Consideration
You should also consider PKCE which is described here https://www.oauth.com/oauth2-servers/pkce/
Specifically, if you are also implementing the Authorization Server then https://www.oauth.com/oauth2-servers/oauth-native-apps/checklist-server-support-native-apps/ states that you should
Allow clients to register custom URL schemes for their redirect URLs.
Support loopback IP redirect URLs with arbitrary port numbers in order to support desktop apps.
Don’t assume native apps can keep a secret. Require all apps to declare whether they are public or confidential, and only issue client secrets to confidential apps.
Support the PKCE extension, and require that public clients use it.
Attempt to detect when the authorization interface is embedded in a native app’s web view, instead of launched in a system browser, and reject those requests.
Web Views Consideration
There are many examples in the wild using Web Views i.e. an embedded user-agent but this approach should be avoided (especially when the app is not first-party) and in some cases may result in you being banned from using an API as the excerpt below from here demonstrates
Any attempt to embed the OAuth 2.0 authentication page will result in
your application being banned from the Fitbit API.
For security consideration, the OAuth 2.0 authorization page must be
presented in a dedicated browser view. Fitbit users can only confirm
they are authenticating with the genuine Fitbit.com site if they have
the tools provided by the browser, such as the URL bar and Transport
Layer Security (TLS) certificate information.
For native applications, this means the authorization page must open
in the default browser. Native applications can use custom URL schemes
as redirect URIs to redirect the user back from the browser to the
application requesting permission.
iOS applications may use the SFSafariViewController class instead of
app switching to Safari. Use of the WKWebView or UIWebView class is
prohibited.
Android applications may use Chrome Custom Tabs instead of app
switching to the default browser. Use of WebView is prohibited.
To further clarify, here is a quote from this section of a previous draft of the best practise link provided above
Embedded user-agents, commonly implemented with web-views, are an
alternative method for authorizing native apps. They are however
unsafe for use by third-parties by definition. They involve the user
signing in with their full login credentials, only to have them
downscoped to less powerful OAuth credentials.
Even when used by trusted first-party apps, embedded user-agents
violate the principle of least privilege by obtaining more powerful
credentials than they need, potentially increasing the attack surface.
In typical web-view based implementations of embedded user-agents, the
host application can: log every keystroke entered in the form to
capture usernames and passwords; automatically submit forms and bypass
user-consent; copy session cookies and use them to perform
authenticated actions as the user.
Encouraging users to enter credentials in an embedded web-view without
the usual address bar and other identity features that browsers have
makes it impossible for the user to know if they are signing in to the
legitimate site, and even when they are, it trains them that it's OK
to enter credentials without validating the site first.
Aside from the security concerns, web-views do not share the
authentication state with other apps or the system browser, requiring
the user to login for every authorization request and leading to a
poor user experience.
Due to the above, use of embedded user-agents is NOT RECOMMENDED,
except where a trusted first-party app acts as the external user-
agent for other apps, or provides single sign-on for multiple first-
party apps.
Authorization servers SHOULD consider taking steps to detect and block
logins via embedded user-agents that are not their own, where
possible.
Some interesting points are also raised here: https://security.stackexchange.com/questions/179756/why-are-developers-using-embedded-user-agents-for-3rd-party-auth-what-are-the-a
Unfortunately, I don't think there is a clear answer to this question. However, here are the options that I've identified:
If it is ok to ask the user for his/her credentials, then use the Resource Owner Password Credentials. However, this may not be possible for some reasons, namely
Usability or security policies forbid the insertion of the password directly at the app
The authentication process is delegated on an external Identity Provider and must be performed via an HTTP redirect-based flow (e.g. OpenID, SAMLP or WS-Federation)
If usage of a browser based flow is required, then use the Authorization Code Flow. Here, the definition of the redirect_uri is a major challenge, for which there are the following options:
Use the technique described in https://developers.google.com/accounts/docs/OAuth2InstalledApp, where a special redirect_uri (e.g. urn:ietf:wg:oauth:2.0:oob) signals the authorization endpoint to show the authorization code instead of redirecting back to the client app. The user can manually copy this code or the app can try to obtain it from the HTML document title.
Use a localhost server at the device (the port management may not be easy).
Use a custom URI scheme (e.g. myapp://...) that when dereferenced triggers a registered "handler" (the details depend on the mobile platform).
If available, use a special "web view", such as the WebAuthenticationBroker on Windows 8, to control and access the HTTP redirect responses.
Hope this helps
Pedro
TL;DR: Use Authorization Code Grant with PKCE
1. Implicit Grant Type
The implicit grant type is quite popular with mobile apps. But it was not meant to be used like this. There are security concerns around the redirect. Justin Richer states:
The problem comes when you realize that unlike with a remote server
URL, there is no reliable way to ensure that the binding between a
given redirect URI and a specific mobile application is honored. Any
app on the device can try to insert itself into the redirection
process and cause it to serve the redirect URI. And guess what: if
you’ve used the implicit flow in your native application, then you
just handed the attacker your access token. There’s no recovery from
that point — they’ve got the token and they can use it.
And together with the fact, that it does not let you refresh the access token, better avoid it.
2. Authorization Code Grant Type
The authorization code grant requires a client secret. But you should not store sensitive information in the source code of your mobile app. People can extract them. To not expose the client secret, you have to run a server as a middleman as Facebook writes:
We recommend that App Access Tokens should only be used directly from
your app's servers in order to provide the best security. For native
apps, we suggest that the app communicates with your own server and
the server then makes the API requests to Facebook using the App
Access Token.
Not an ideal solution but there is new, a better way to do OAuth on mobile devices: Proof Key for Code Exchange
3. Authorization Code Grant Type with PKCE (Proof Key for Code Exchange)
Out of the limitations, a new technique was created that let you use the Authorization Code without a client secret. You can read the full RFC 7636 or this short introduction.
PKCE (RFC 7636) is a technique to secure public clients that don't use
a client secret.
It is primarily used by native and mobile apps, but the technique can
be applied to any public client as well. It requires additional
support by the authorization server, so it is only supported on
certain providers.
from https://oauth.net/2/pkce/
Using a webview in your mobile application should be an affordable way to implement OAuth2.0 protocol on Android platform.
As for redirect_uri field, I think http://localhost is a good choice and you don't have to port a HTTP server inside your application, because you can override the implementation of onPageStarted function in the WebViewClient class and stop loading the web page from http://localhost after you check the url parameter.
public void onPageStarted(final WebView webView, final String url,
final Bitmap favicon) {}
The smoothest user experience for authentication, and the easiest to implement is to embed a webview in your app. Process the responses received by the webview from the authentication point and detect error (user cancel) or approval (and extract token from url query parameters).
And I think you can actually do that in all platforms. I have successfully made this work for the following: ios, android, mac, windows store 8.1 apps, windows phone 8.1 app. I did this for the following services: dropbox, google drive, onedrive, box, basecamp. For the non-windows platforms, I was using Xamarin which supposedly does not expose the entire platform specific APIs, yet it did expose enough for making this possible. So it is a pretty accessible solution, even from a cross platform perspective, and you don't have to worry about the ui of the authentication form.

server-to-server REST API security

We're building a REST API that will only be accessed from a known set of servers. My question is, if there is no access directly from any browser based clients, what security mechanisms are required.
Currently Have:
Obviously over HTTPS
Have HTTP auth enabled, API consumers have a Key & password
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed for the request and validated at the endpoint?
Use OAuth (2-legged authentication)?
Doesn't matter - from browser or not.
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed
for the request and validated at the endpoint?
Use oauth (2-legged authorization)?
Use OAuth, it solves both these questions. And OAuth usage is good because:
You aren't reinventing wheel
There are already a lot of libraries and approaches depending on technology stack
You can also use JWT token to pass some security context with custom claims from service to service.
Also as reference you can look how different providers solve the problem. For example Azure Active Directory has on behalf flow for this purpose
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-on-behalf-of-flow
Use of OAuth2/OpenID Connect is not mandatory between your services, there are other protocols and alternatives and even custom. All depends in which relationships are services and either they both are in full trust environment.
You can use anything you like but main idea not to share sensitive information between services like service account credentials or user credentials.
If REST API security is main requirement - OAuth2/OpenID Connect is maybe the best choice, if you need just secure (in a sense of authentication) calls in full trust environment in a simplest way - Kerberos, if you need encrypted custom tunnel between them for data in transit encryption - other options like VPN. It does not make sense to implement somthing custom because if you have Service A and Service B, and would like to make sure call between them is authenticated, then to avoid coupling and sharing senstive information you will always need some central service C as Identity provider. So if you think from tis pov, OAuth2/OIDC is not overkill
Whether the consumers of your API are web browsers or servers you don't control doesn't change the security picture.
If you are using HTTPs and clients already have a key/password then it isn't clear what kind of attack any other mechanism would protect against.
Any compromise on the client side will expose everything anyway.
Firstly - it matters whether a user agent (such as a browser) is involved in call.
If there are only S2S calls then 1 way SSL HTTPS (for network encryption) and some kind of signature mechanism (SHA-256) should be enough for your security.
However if you return sensitive information in your api response, its always better to accept 2 way ssl HTTPS connections (in order to validate the client).
OAuth2 doesn't add any value in a server to server call (that takes place without user consent and without any user agent present).
For authentication between servers:
Authentication
Known servers:
use TLS with X.509 client certificates (TLS with mutual authentication).
issue the client certificates with a common CA (certificate authority). That way, the servers need only have the CA certificate or public key in the truststore, and new client certificates for additional clients/servers can be issued without having to update the truststores.
Open set of servers:
use API keys, issued by a central authority. The servers need to validate these keys on each request (and may cache the hashes of the keys along with the validation result for some short time).
Identity propagation
if the requests are executed in the context of a non-technical user, use JWT (or SAML) for identity propagation of the user principal and claims (authorize at security proxy/WAF/IAM, and issue JWT signed by authentication server).
otherwise the user principal refers to the technical user and can can be extracted from the client certificate (X.509 DName) or be returned with a successful authentication response (API key case).

Resources