How to detect if a federated Identity Provider has MFA configured? - identityserver4

I'm planning to federate external Identity Providers (Google,Microsoft,GitHub,...) to my applications.
In my applications for security reasons we want MFA to be enabled for every user.
Is there any way to detect if the user authenticated himself using "Google" with MFA?
I understand that federating an external Idp, the user identification responsibility is transferred to the external Idp, so I doubt that what I'm asking would be possible.
Thanks in advance.
OaicStef
P.S.: In my applications, I manage the authentication with Identity Server 4.

The amr claim is what you're looking for but it's optional so it's not for certain that all providers will provide it and if they do they may provide the data in different ways - e.g. one might return ["pwd","otp"] to describe a situation where a password and a one-time code were used and another may just just use "mfa".
The best thing to do would be to experiment and observe what each service does both with and without MFA enabled and adapt as neccessary.
If it's not something you can guarantee then there's also the option of implementing your own MFA features - libs for using TOTP-based authenticator apps or FIDO2/WebAuthn are readily available.

Related

Linking External Identity Users With Existing Users

I'm adding an external identity provider, Azure multi-tenant, as a login option. I have local accounts right now and they know nothing about Azure AD users.
I want to create an Azure Enterprise App that other tenants can use to set up SSO using OpenID Connect. Also I want the app to support User Provisioning by setting up a SCIM API.
I can't really find any documents on how to handle linking Azure AD users with the existing accounts in my IDP. I've seen examples where users can login using their local account, authenticate with Azure, and then their local account is updated to have the Azure AD User ID. This approach still seems pretty manual. Another thought was to have a step in the login journey, where if no local account has the Azure AD User ID then find a local account with the same email. I don't like this approach either since the emails might not always match. Is there an approach where an admin can automatically link all accounts with a sync or upload?
SYSTEMS
First it's worth clarifying roles:
Role
Details
Authorization Server (AS)
Your UIs and APIs receive tokens from this. It is where accounts and linked accounts are stored. It is where you use SCIM to update account records. It is where you apply account linking logic.
Identity Provider (IDP)
There can be multiple of these. When your apps call the AS it manages connections to them, and exchanges IDP tokens for AS tokens that are returned to apps. It is not usual to use SCIM against an IDP.
You are using IdentityServer as the AS so your UIs and APIs will continue to use IdentityServer tokens and remain simple. Meanwhile Azure AD will become an alternative IDP. So on the data side of things your architecture is in a good place.
AUTHENTICATION ACTIONS
I would aim to solve your problems via custom authentication actions, and to design this in a vendor agnostic way. Not all providers support these concepts, but IdentityServer has some pretty good extensibility features, so hopefully it has what you need.
A bit of code, configuration and technical investigations in IdentityServer feel like the correct direction, with no complexity added to your applications. I will describe techniques in terms of Curity (where I work), but the same principles can apply to any system.
USERNAME AUTHENTICATOR
A great way to deal with user specific differences is to make the initial screen prompt only for an email. See this example for how that looks. Later, when authentication has completed, you could set a cookie so that this screen is not shown on subsequent logins.
Then, before asking for credentials, apply some scripted logic, eg to look up existing account attributes, and decide how the user should authenticate. You might decide to route unknown users to Azure AD or do something based on business partner email suffixes.
DATA UPDATES
Something simple that might work in advance of adding Azure AD support is to assign all users a Tenant ID, and perhaps existing users get a Tenant ID of 1. Only those users are allowed to sign in with Identity Server - all others have to use Azure AD.
SCRIPTED LOGIC AND ACCOUNT LINKING
For a worked example of how this looks, see this Account Linking with Facebook tutorial. In this example the objective is to update the main account with a new linked account. This account linking doc may give you some additional ideas for your scenario. It should be possible to run custom logic before triggering authentication or once your have the Azure IDP attributes.
INVOLVE THE USER IF NEEDED
It may also be useful to present a custom screen to ask the user if they have an existing account when they first login via Azure AD. If not then an Azure AD login can create the primary account in IdentityServer data in addition to a linked account.
USERS AND PARTNERS
How users onboard is interesting, and discussed in this detailed article. I always start by getting a feel for the type of assets involved:
Type
Description
Personal Assets
You allow any user to sign up and they only have access to their own assets
Corporate Assets
Users are provisioned by an administrator, eg a banker is granted access to financial data according to business rules
In your case it feels like users are from the second category, so to enable a user to fully sign up you need data from the partner, either fed in manually or by getting them to call your API, before you can assign the user the correct tenant ID. This might eventually result in TenantID=23, but there is nothing to stop you initially allowing users to onboard and placing them in a default TenantID=0 bucket.
Ultimately this all comes down to data, claims and API authorization. Eg APIs could return certain data to TenantID=0 users but only return privileged data to users whose tenant ID has been asserted by an administrator. Not sure if these thoughts of mine match your scenario but hopefully they provide a useful hint or two.
SUMMARY
Reliable account linking is tricky, but it should be solvable via the building blocks of the Authorization Server, using the above techniques. The end result should be deterministic user data, with no duplicate users.

Google authentication, verify to skeptic

Google supports several identity verification flows for third parties:
https://developers.google.com/identity/choose-auth
Looking at OAuth, the cryptographic primitive is that I can connect using HTTPS and Google can assert to me the identity of the visitor.
This method does not allow me to prove to another skeptic that this certain person completed Google login. This is because HTTPS is plausible deniable.
Is there a different login mechanism for Google where I can prove to a third party that a certain person logged in?
I'm not sure if plausible deniability in the cryptographic sense is applicable to HTTPS - if I understand it correctly you'd need specific support for multiple keys decoding the message in different ways for that, i.e. special software, not just HTTPS.
But regardless, Google authentication (and any other 3rd party identity provider service) fundamentally relies on the trust in the information coming from the identity provider.
If you don't consider the 3rd party identity provider supplied information good enough as proof for another skeptic then you won't be able to use any such identity provider service, you'd have to roll out your own authentication scheme.

IdentityServer4 vs Auth0

We want to build a central authority to do authentication and authorization for our various applications (.net). We see IdentityServer4 is open source and free, while Auth0 cost money. Does anyone use both of these? Can anyone provide suggestion which one to choose and why?
IdentityServer is a library that implements various authentication (not authorization!) protocols and let's you consolidate access control into a single system. You can host it in a typical ASP.NET webapp, console app or anything else, as long as the HTTP endpoints are available. It also lets you store the user data anywhere you want, whether in-memory, databases, flat files, the asp.net core membership system, or anywhere else.
Auth0 is a company that provides a managed service that handles authentication for you. They run the infrastructure and provide access through their website and APIs. It's similar to having someone run IdentityServer4 for you and there are several competitors like Okta for Devs, AWS Cognito, Azure AD B2C, Google Cloud Identity/Firebase, and more.
Choose IdentityServer if:
You want free open-source software.
You have the time and effort to run it yourself.
You want to control the backing data store (SQL database, Redis, JSON file, etc).
You want to manage all the data yourself due to regulations, privacy, etc.
You need complete control and flexibility around what happens during authentication (for example, merging user accounts in your database when someone signs in). It's all just C# code so you can do whatever you want.
Choose Auth0 if:
You want to save time and effort on implementation and operation.
Price is not an issue (as it can get expensive for some features).
The limited customizations offered by Auth0 are enough for your app.
You want the other features they offer like password-breach monitoring.
You don't want to manage user data, or don't mind having it stored by them.
Update as of Oct 2020 - IdentityServer is now a product from Duende Software with a new commercial open-source license to sustain development. There are other alternatives like OpenIddict that are still free.
Identity Server means building a server application to handle authentication and authorization, which can replicate what Auth0 does for OpenIdConnect (OIDC) there will be a few things to implement even if you use IdentityServer4. You will need to build that first, then integrate your application.
Auth0 allows you to integrate immediately with OIDC with additional & enterprise features.
Both of them implement federated protocols i.e. WS-Fed, SAML and OpenID Connect.
In order to use them your apps. need the appropriate client-side stack.
If they don't have this, you can't use the products.
The only alternative is pass-through, i.e. Auth0.
Or look at ADFS which has pass-through via the ADFS WAP.
If you do have the stacks, both will do the job.
idsrv4 does not have a user management portal e.g. create user, add group to users OOTB.
Auth0 does.
idsrv4 essentially adds features by code. Auth0 has config. via wizard.
idsrv4 is open source so you can customise to your heart's content. I find it really useful to bridge systems.
Azure AD is another option.

SAML or CDSSO based approach feasibility

I was just playing around with OpenAM and found that authentication can be done through SAML as well as cookie based approach of CDSSO. Now my concern is if I am working in domain like banking and healthcare how feasible it would be to go for CDSSO cookie based approach and is their any organization who is practicing cookie based approach in any such domain.
SAML is designed for connecting independent security "domains". The term "domain" in this instance has nothing to do with network domain names, but a rather more nebulous term, meaning a division between security systems. An example to explain a bit better: Company A uses OpenAM to protect its intranet websites, but they also use services from Salesforce. SAML is the obvious choice here - Salesforce isn't going to use a cookie from OpenAM... How could they? You could also use it to interconnect two different systems inside a company (and domain name), like OpenAM and Siteminder, since those two systems can't communicate directly via their cookies.
CDSSO is primarily designed for use inside an organization that could have multiple domains that they protect. They can have multiple policy servers in multiple domains, but all of those servers are managed by the same OpenAM instance, and they all share a common backend. Lots of organizations use OpenAM's (and OAM's, and Siteminder's) CDSSO capabilities. But they use it inside the systems within their control.
In addition, I can't think of a single service provider that would want you to place one of your OpenAM policy servers inside their network. You wouldn't want them touching your server, and they wouldn't (if they are right in the head) trust you to not be dropping a trojan in their network.
TL;DR:
SAML - outside of an administrative domain
CDSSO - inside an administrative domain
SAML is the standards based way of achieving SSO for, Agents is the proprietary way.
SAML does not offer any authorization (which user is allowed access to a given resource) out-of-the box ... that's the backdraw.

Google App Engine Go - using OpenID, should I also use captcha?

Currently I'm developing a GAE application in golang that would allow the users to log into the service using OpenID from Google. Each account would be mapped to one Google account obviously. Should I implement captcha for user registration, or does using the OpenID already prevent the service from a bot attack?
Are you accepting any OpenID? Then this is not sufficient protection. Anyone can put up an OpenID site on their own domain, use a script to create a billion accounts, and log in with one of them on your site.
Are you accepting only specific OpenID providers? Then you're not using OpenID as it was meant to be used (and, in fact, expressly the opposite of why it was created). But the answer then would be: do you trust that the OpenID providers have done their own due diligence at the time of account creation to prevent spam accounts?
Regardless, you'll likely find that captcha's a poor solution, and currently all implementations of it are broken (but that's a whole different topic).
First of all, fear of a bot attack is really a preliminary caution. Parsing CSRF tokens (which you should use anyway) and dealing with cookies would already cause enough pain to an attacker. I doubt anyone would trouble himself into setting up very own OpenID provider which is the only way one can do that.
Secondly, App Engine's OpenID Federated Login is the User API feature, not Go runtime's one — you can use any OP with it (Facebook, Yahoo!, Steam... Google). User API provides two modes (configurable via Application Settings): OpenID Federated Login and Google Accounts sign in. Which to pick depends on requirements. If all you need is user's Google account you'd better use the latter, when if it's simple password-less sign in with nearly everything, choose OpenID. From the app's perspective both look identical. Best way to go is OAuth, though.
Getting back on the question, both Google Accounts API and OAuth would make such attacks almost impossible and with OpenID it is a little simpler.
https://developers.google.com/appengine/docs/go/users/overview

Resources