Is ForceAuthn=true good idea for Service Provider - security

Looking for guidance to understand the use case behind ForceAuthn=true for SAML-driven Single Sign-On.
We know that ForceAuthn=true will always challenge the user for credentials which creates friction thus negative experience for the user.
However, that's UX story. What about security?
If ForceAuthn=false, I authenticate once and the second time a seamless login will happen.
This might create an issue where unware user using public PC can leave the access open for the next person.
If you have are (or work) for a provider (e.g. SaaS) and have SAML-driven SSO with clients, what is your policy/experience around this topic?

It's not common for service providers to set ForceAuthn=true. As the service provider, it's not your decision on how to authenticate a user when you are entrusting that process to the identity provider. And, what happens when the IdP is using a non-interactive authentication mechanism like Kerberos? While they may see the redirects occurring, there's no user interaction with or without forcing authentication. Point being, if you're outsourcing authn, then outsource it, and then have the IdP indemnify you for anything around authentication.
What I do see service providers doing is using ForceAuthn=true to use as "singular transaction authorization" like for authorization of steps in workflows and digital signing.

Related

How does an Azure Active Directory app registration establish trust?

The Microsoft docs state:
Registering your application establishes a trust relationship between your app and the Microsoft identity platform. The trust is unidirectional: your app trusts the Microsoft identity platform, and not the other way around.
What exactly is meant by "trust" here and how does the app registration establish said trust?
The way I understand it the registration basically makes the app known to the AD, but how does that make the AD, the app is redirecting to for interactive logins, more trust-worthy to the app? Couldn't a malicious AD just pretend to know any app that's using it for logins? Wouldn't it need some kind of shared secret to assure the app that the AD really is the AD? And isn't HTTPS establishing that trust already?
It makes more sense to me the other way around: the AD receives a login request along with a redirect URI set by the app. But if the redirect URI is not known to the AD then the request is not trust-worthy and will be rejected.
I'm probably misunderstanding something, so could someone please explain the idea behind this?
In authentication world trust is a complicated word. In my opinion, the easiest way to approach this thing is taking the Google Sign-In -button as an example. You can use it to log in with your Google account on almost every website out there. Does this mean Google trusts every website out there using it? No, of course not. Do those websites trust Google? Sure they do, they have no visibility if Google returns the correct information about the users to them.
The case is very similar here as in most cases you will be using the same protocol to implement it (OAuth2 OIDC).
You are correct, you need to configure secrets & returnUrls to make sure that the App Registration is not used for malicious purposes, however, this does not create trust between the identity provider and the application. It's just technical measures to protect the client.
However, you can of course trust the application if you want to. The most common way is to grant it access to scopes so the application can do actions on behalf of the user. Usually this is done by those consent screens you probably know ("grant access to your email and phone number"). In enterprise setting, they are often omitted and access is granted with admin constent.
TL;DR; There is no inherit trust just because there is an App Registration, however you can trust an app to access user data.

Method for site wide authentication?

I am currently looking for a method to provide site wide authentication, for services exposed to the cloud, on the site I am responsible for. Some services are a Python based, some in PHP and some in Perl. Individual services would need to be able to get access to the user profile and the associated roles.
On the main page users are logged in and a cookie is created using a JWT token. The main site is using NodeJS for the auth system and is built in-house.
At this point I am wondering whether we should use OAuth2 across the site or whether there is another approach that may be simpler, where we don’t need to deal with inter domain requirements?
The approach you're currently investigating is the re-use of a JWT as an authentication token across multiple services. Although it's technically possible - it is not the ideal secure approach.
The most secure approach is for separation of application contexts, whereby each application should be tied to a different application credential (in OAuth2 terms). This is ensures that the user receives a credential unique to that application, allows the credentials to be managed/revoked separately and audited in isolation.
To implement this smoothly for UI flows requires an identity provider that supports SSO, and also assumes that each UI application can handle negotiation to the IDP to access that SSO session.
For interactions that are system to system authenticated, eg. Python, you would need to use system to system authentication (OAuth2 client credentials) that again have its own credential. In the case where you need access to the end-user's profile, a management api key (or similar) would be required.

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.

Validate user in Azure Active Directory; Not using SSO but using username and password

With the recent release of Azure AD, we would like to use Azure AD for our web application authentication, but we do not want to use SSO. We do not want users to be redirected to the Microsoft Account login screen, and then come back. We want to supply them with the login credential screen where we capture their username and password, and then we want to programatically do the authentication against Azure AD, and get back the claims identity.
The problem I have is that I cannot see how I can do that using the Graph API, and all the examples that look like it might work, only works on the previous [0.8] release. There is such a mix of examples that is supposed to work, but they don't simply because of the new release.
Can anyone tell me if this is even possible, and maybe point me in the direction of how to do it please.
I do not want to use ACS.
What you are asking for is not technically possible with Azure Active Directory today. That scenario could possibly be supported in the future, so check back from time to time.
We really encourage developers to rely on the in browser sign in experience. The reason is that because the browser allows the server to define the experience, it allows for much greater flexibility with respect to the kinds of credentials that can be employed. For instance, if you code your app to use only username and password, then it may need to be updated in order to take advantage of two factor authentication. If you rely on the browser based experience then your app can be totally agnostic to whether 2FA is being employed, or any other kind of authentication dance.
We recognize that there are some scenarios where this is not ideal or even practical and are looking at solutions to those scenarios that may be supported in the future.

Azure ACS beginner approach

I know there are a lot of questions about Azure ACS, but I want to ask a more general one:
Should I use ACS, or it's not worth the effort? :)
What I want is a secure WebService in Azure that will be called from 2 places: a mobile app and another service inside Azure. Users will never access this webService directly.
Thanks
Update:
I don't care much about the identity of the user that is behind my mobile app.
I think it depends on the specific scenario, you say that users will not access the service dicrecly, but presumably it is the user who will use the mobile and/or web app.
Thinking of authentication and authorisation - if all you need to do is identify that you're coming from your own appilcation, than there are defintiely leaner approaches. simple certificate based solution would do, or even username/password based solution.
If, however, you wish to use the identity of user beheind the app to drive the authentication and authorisation for the service, than you do need to worry about the user's identity, and of course you can manage it yourself, but this is where the ACS comes very handy in that it lets you leverage one or more existing identity providers, which makes it easier for you and the user.
It's probably not worth it.
ACS is great for managing user identity on your behalf: in other words, for allowing your users to make identity claims.
If your Web service needs to know about your users' identities then it's definitely worth the (small) effort to implement, as it takes care of much of the work for you.
If your Web service doesn't know about user identity, and there's no external endpoint defined for the service -- then, yes, I'd not bother with ACS either.

Resources