Wednesday, December 16, 2015

IdentityServer : The WebApp-OpenIDConnect-DotNet Azure AD sample

I use this sample a lot - Azure-Samples/active-directory-dotnet-webapp-openidconnect.

I've also been looking at idsrv3 lately - mainly from the enterprise PoV i.e. WS-Fed and SAML

idserv3 also supports modern authentication i.e. OpenID Connect and OAuth2.

So I wondered if this sample would work on idsrv3?

As per OpenID Connect Hybrid Flow and IdentityServer v3:

"Lastly, hybrid flow is the only flow supported by the Microsoft OpenID Connect authentication middleware (in combination with a form post response mode)"

Hybrid flow is described in the article. The above tells us that idsrv3 has to be hooked up using the hybrid flow.

(BTW - the idsrv3 equivalent sample is here - Clients/MVC OWIN Client (Hybrid)).

Turns out the changes are minimal - as you would expect.

In Startup.Auth.cs:

private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];

string authority = String.Format(CultureInfo.InvariantCulture, aadInstance);

public void ConfigureAuth(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType
        (CookieAuthenticationDefaults.AuthenticationType);
    
    app.UseCookieAuthentication(new CookieAuthenticationOptions());

    app.UseOpenIdConnectAuthentication( 
        new OpenIdConnectAuthenticationOptions
        {
            ClientId = clientId,
            Authority = authority,
            RedirectUri = postLogoutRedirectUri,
            PostLogoutRedirectUri = postLogoutRedirectUri,
            Notifications = new OpenIdConnectAuthenticationNotifications


The only change was to add the RedirectUri.

Note that I tried to minimise the changes so I kept the AADInstance variable even though Azure AD is not involved.

web.config:

<add key="ida:ClientId" value="katanaclientad" />
<!--<add key="ida:Tenant" value="[Enter tenant name, e.g. contoso.onmicrosoft.com]" />-->
<add key="ida:AADInstance" value="https://localhost:44333/core" />
<add key="ida:PostLogoutRedirectUri" value="https://localhost:44320/" />

On the idsrv3 side, we need a new Client:

Host-Configuration/Client.cs

new Client
{
    ClientName = "Katana Hybrid Client Demo - AAD Sample",
    Enabled = true,
    ClientId = "katanaclientad",
    ClientSecrets = new List<Secret>
    { 
        new Secret("secret".Sha256())
    },

    Flow = Flows.Hybrid,
                    
    AllowedScopes = new List<string>
    {
        Constants.StandardScopes.OpenId,
        Constants.StandardScopes.Profile,
        Constants.StandardScopes.Email,
        Constants.StandardScopes.Roles,
        Constants.StandardScopes.OfflineAccess,
        "read",
        "write"
    },
                    
    ClientUri = "https://identityserver.io",
    LogoUri = [snip]

    RequireConsent = false,
    AccessTokenType = AccessTokenType.Reference,
                    
    RedirectUris = new List<string>
    {
        //"http://localhost:2672/",
        "https://localhost:44320/",
    },

    PostLogoutRedirectUris = new List<string>
    {
        //"http://localhost:2672/"
        "https://localhost:44320/",
    }
},

The changes to display the claim are as per: IdentityServer : Identity Server 3 as a WS-Federation IDP with an ASP.NET MVC application.

 So we navigate to the sample, click the "Sign In" link. it redirects to idsrv3, we can authenticate with "alice / alice" or "bob / bob", back to the sample, click the Contact tab and the claims are displayed as below:

Claim Type Claim Value
nonce 635858209323.....Tk5YjYtNjU1NzU2ZWU4MzU5
iat 1450224140
c_hash 0ibKE6.....uZcbGR_A
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier 818727
http://schemas.microsoft.com/claims/authnmethodsreferences password
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant 1450224139
http://schemas.microsoft.com/identity/claims/identityprovider idsrv
name Alice Smith
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname Alice
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname Smith
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage http://alice.com
iss https://localhost:44333/core
aud katanaclientad
exp 1450224440
nbf 1450224140

Enjoy!

Monday, December 14, 2015

AAD : The default WS-Federation claims

I have an ASP.NET RP using OWIN WS-Fed to talk to an ADFS instance and this ADFS instance has Azure AD as a CP.

For reference, this is the default claims set from AAD:

Claims from ClaimsIdentity

Claim Type Claim Value
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier QY7TN_h.....vFbw9IKD-nY
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress joe.bloggs@company.com
http://schemas.microsoft.com/identity/claims/tenantid 4ef13bb.....a8291aeded
http://schemas.microsoft.com/identity/claims/objectidentifier 8f803ba.........63-eacba54
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name joe.bloggs@company.com
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname joe
http://schemas.microsoft.com/identity/claims/displayname joe bloggs
http://schemas.microsoft.com/identity/claims/identityprovider https://sts.windows.net/4e.....df-ad5a8d/
http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent Mozilla/5.0 (Windows NT 6.3; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0
http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path /adfs/ls/
http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork true
http://schemas.microsoft.com/2012/01/requestcontext/claims/client-request-id 0000.....0-0080e7
http://schemas.microsoft.com/2012/01/requestcontext/claims/relyingpartytrustid https://my-pc/WebApp-ADFS-DotNet/
http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-ip 111.11.111.111
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant 2015-12-13T19:12:58.920Z

Sadly, there is no way currently to alter this default set other than to use Microsoft Graph to get the claims yourself.

Note that because AAD is built on a Graph platform, a lot of the values are actually GUID's.

Enjoy!

ADFS : Passing all the claims over

If you are troubleshooting / debugging an IDP - RP claims setup in ADFS, a neat trick is to just have the following custom rule on both the IDP and RP:

c:[] => issue(claim = c);

This passes all the claims over so you can see exactly how the user is set up in the repository you are authenticating against.

Then you can fine-tune the claims rules to pass-through / transform or whatever.

Enjoy!

Friday, December 11, 2015

ADFS : Using Azure AD

I'm frequently asked about using Azure AD together with ADFS, AAD is becoming far more prevalent, mainly because of the popularity of Office 365 (which uses AAD under the hood).

There are a number of ways of doing this.

The first is the DirSync / AAD Connect route where the AD attributes are synched up to AAD. The AAD tenant becomes a federated tenant and relies on ADFS for authentication.

The second is where ADFS is added as a custom SAML application - refer : Configuring single sign-on to applications that are not in the Azure Active Directory application gallery. 

I don't recommend doing it this way - just including this for completeness.

The third way - and by far the easiest - is just to federate them. Import the AAD metadata (the endpoint link is at the bottom of an AAD Application) into ADFS and then configure AAD as per the second scenario in WAAD AS IdP.

Note that the URI is http rather than https (because it's the entityID).

This is also documented in this post (just ignore the SharePoint stuff).

Enjoy!

IdentityServer : The power of extensibility

The previous post compared idsrv3 to other Microsoft Identity products from a protocol perspective.

From a wider perspective, a key point is that it is extensible.

ADFS 2.x ran on IIS and was essentially a web application.

This meant you had access to the form code, css and html. As a result, you could extend ADFS by hiding providers in the HRD, adding MFA, allowing different kinds of user names, displaying why authentication failed e.g. account lockout and so on.

However, it resulted in a number of "insecure" installations and so the architecture of ADFS 3.0 onwards changed to a black box running on http.sys (and thus no IIS) with very limited customisation

ADFS and Azure AD are pretty much locked down and there is a good argument for supporting this approach.

idsrv3 takes the opposite approach - it is designed to be extensible and supports plugging in Katana middleware.

Katana allows you to pick and choose functionality you want - both vertically (the ASP.NET framework) and horizontally (you can mix and match authentication e.g. FBA, WS Fed, SAMLp and certificate in the same application).

In addition, it's open source so you can enhance it any way you like e.g. custom login workflows / registration etc. Ideally, all the enhancements should be done using the extensibility points rather than altering the code.

I've used it in a number of projects to essentially extend ADFS by federating ADFS and idsrv3 and then "altering" and "extending" on the upstream and downstream paths.

Unlike ADFS, idsrv3 has no dependency on AD. It does not need to be installed on a domain controller and can be hosted in IIS, NT Services, embedded, on-premises or in the cloud on Azure or AWS.

However, with great power comes great responsibility. idsrv3 is a certified security product.

Review any changes you make from a security point of view.

Enjoy!

Wednesday, December 09, 2015

IdentityServer : Comparing IdentityServer to other Microsoft Identity products

I've just done a series of posts on IdentityServer 3 and I thought it would be a good idea to sum it all up.

I'm looking at the protocols supported for purpose of comparison.



Identity Server 3
Azure AD
ADFS 3.0
(2012 R2)
ADFS 4.0? (2016 vNext)





Authenticate against
In Memory
ASP.NET Identity
Membership Reboot
(interface can be extended to any repository)
Azure AD Graph
AD
AD
LDAP v3
SQL Server





WS-Federation
Y
(via Katana extension)
Y
Y
Y





SAML 2.0
Y
(via Katana extension)
Y
Y
Y





OpenID Connect
Y
Y
N
Y





OAuth 2.0
Y
All profiles

Y
All profiles

Y
Authorisation Code Grant confidential client profile only
Y
All profiles






Social
Google
Twitter
Facebook
(can be extended via Katana extension)
Azure ACS / B2C
Via federation with Azure ACS / B2C
Via federation with Azure ACS / B2C


 


Azure ACS = Windows Live / Google / Yahoo / Facebook

Azure B2C = Facebook / Google+ / Amazon / Linkedin

As you can see, IS compares really well and offers a wider selection than ADFS 3.0.

See also: IdentityServer : The power of extensibility

Enjoy!

ADFS : Federating two instances of ADFS

This is a common scenario. One ADFS is the CP and one is the RP.

This is using ADFS 3.0.

The authentication flow is:

Application --> ADFS RP-STS --> ADFS CP --> Authenticate

The RP-STS indicates that the flow is just passing through this.

The federation is done in the usual manner by importing the metadata.

For convenience, we'll use ADFSR for the R-STS instance and ADFSC for the CP instance.

For ADFSC, ADFSR is configured as a RP.

For ADFSR, ADFSC is configured as a CP. This means that ADFSC will appear on the HRD screen of ADFSR.

Looking at the ADFSC tabs as configured on ADFSR:

The Identifier is http://adfsc/adfs/services/trust

The Certificate is the ADFS Signing certificate for ADFSC

The Encryption is the ADFS Encryption certificate for ADFSC

The Endpoints are:
  • ADFSC WS-Fed Passive Endpoints
  • ADFSC SAML Artifact Resolution Endpoints
  • ADFSC SAML SSO Endpoints
  • ADFSC SAML Logout Endpoints

Looking at the ADFSR tabs as configured on ADFSC:

The Identifiers are:

http://adfsr/adfs/services/trust
http://adfsr/adfs/ls
Some http://adfsr/adfs/services/trust/13 and http://adfsr/adfs/services/trust/2005

The Signature is the ADFS Signing certificate for ADFSR

The Encryption is the ADFS Encryption certificate for ADFSR

The Endpoints are:
  • ADFSR WS-Fed Passive Endpoints
  • ADFSR SAML Artifact Resolution Endpoints
  • ADFSR SAML SSO Endpoints
  • ADFSR SAML Logout Endpoints
Enjoy!

Tuesday, December 08, 2015

IdentityServer : ASP.NET MVC application to idsrv3 to ADFS via SAMLp 2.0

This continues the series of blogs I've done on IdentityServer 3.

This scenario involves idsrv3 as both an IDP to an ASP.NET MVC application and as a RP to ADFS. Also I'm using the InMemory option.

So the authentication chain is:

RP --> WS-Fed --> IS --> SAMLp 2.0 --> ADFS

Normally you would federate to ADFS via WS-Fed. However, in this scenario I want to use the
Kentor.AuthServices SAMLp stack so I'm using ADFS as a SAMLp IDP.

ADFS is v3.0. IS is version 3. This is being invoked by the Host.Web sample in idsrv3.

This builds on  IdentityServer : ASP.NET MVC application to idsrv3 to Kentor.AuthServices via SAMLp 2.0

Note by SAMLp 2.0 I mean the SAML protocol, not the SAML token.

The code in IdentityServerExtension.cs in the Host.Configuration project of idsrv3 would look like:

var authServicesOptions = new KentorAuthServicesAuthenticationOptions(false)
{
    SPOptions = new SPOptions
    {
        EntityId = new EntityId("http://localhost:44333/core")
    },

    SignInAsAuthenticationType = signInAsType,
    AuthenticationType = "saml2p",
    Caption = "SAML2p",
};

Uri metadataURI = new Uri("https://adfs.local/federationmetadata/2007-06/federationmetadata.xml");

authServicesOptions.IdentityProviders.Add(new IdentityProvider(
    new EntityId("http://adfs.local/adfs/services/trust"),
    authServicesOptions.SPOptions)
    {
        MetadataUrl = metadataURI,
        LoadMetadata = true,
    });

app.UseKentorAuthServicesAuthentication(authServicesOptions);

Now we need to configure ADFS. The idsrv3 metadata at core/wsfed/metadata refers only to WS-Fed not to SAMLp so we need to do this manually.

From the ADFS side, idsrv3 is a RP so we need to add a new RP.

Identifier tab:


We can leave out the certificates for the purposes of this exercise.

Endpoint tab:


where the second endpoint is:

https://localhost:44333/core/AuthServices/Acs

Under the Advanced tab, set the hash algorithm to SHA-1.

The claims rule mappings are exactly the same as per:

IdentityServer : ASP.NET MVC application to idsrv3 to ADFS

Then run up the MVC application. This should redirect to the idsrv3 Login screen. Click the SAML2p button, Authenticate on ADFS. You should be redirected back to the application, click the Contacts tab and you should see the claims displayed

If you want to see the actual SAML messages, use the excellent SAML tracer.

Enjoy!

IdentityServer : ASP.NET MVC application to idsrv3 to Kentor.AuthServices via SAMLp 2.0

This continues the series of blogs I've done on IdentityServer 3.

This scenario involves idsrv3 as both an IDP to an ASP.NET MVC application and as a RP to Kentor.AuthServices. Also I'm using the InMemory option.

So the authentication chain is:

RP --> WS-Fed --> IS --> SAMLp 2.0 --> Kentor.AuthServices

IS is version 3. This is being invoked by the Host.Web sample in idsrv3.

This builds on IdentityServer : ASP.NET MVC application to idsrv3 to ADFS. 

Note by SAMLp 2.0 I mean the SAML protocol, not the SAML token.

You need these NuGet packages:

Kentor.AuthServices

Kentor.AuthServices.Owin

Refer to the idsrv3 documentation.

The code in IdentityServerExtension.cs in the Host.Configuration project of idsrv3 would look something like:

var adfs = new WsFederationAuthenticationOptions
{
    AuthenticationType = "adfs",
    Caption = "ADFS",
    SignInAsAuthenticationType = signInAsType,

    MetadataAddress = "https://adfs.local/federationmetadata/2007-06/federationmetadata.xml",
    Wtrealm = "urn:idsrv3rp"
};
app.UseWsFederationAuthentication(adfs);

var authServicesOptions = new KentorAuthServicesAuthenticationOptions(false)
{
    SPOptions = new SPOptions
    {
        EntityId = new EntityId("http://sp.example.com")
    },

    SignInAsAuthenticationType = signInAsType,
    AuthenticationType = "saml2p",
    Caption = "SAML2p",
};

authServicesOptions.IdentityProviders.Add(new IdentityProvider(
    new EntityId("http://stubidp.kentor.se/Metadata"),
    authServicesOptions.SPOptions)
    {
        LoadMetadata = true,
    });

app.UseKentorAuthServicesAuthentication(authServicesOptions);

Note the ADFS section is just for context.

You need the following includes:

    using Kentor.AuthServices;
    using Kentor.AuthServices.Owin;
    using System.IdentityModel.Metadata;

You do not need to make any changes to the app / web.config.

The link in the code above viz. http://stubidp.kentor.se/Metadata points to a test SAMLp IDP which is a cool idea,

Then run up the MVC application. This should redirect to the idsrv3 Login screen. Click the SAML2p button, Authenticate on the test IDP (you can select different users from the dropdown). . You should be redirected back to the application, click the Contacts tab and you should see the claims displayed.

If you want to see the actual SAML messages, use the excellent SAML tracer.

Enjoy!

Monday, December 07, 2015

IdentityServer : ASP.NET MVC application to idsrv3 to Azure Active Directory

This builds on  my previous post IdentityServer : ASP.NET MVC application to idsrv3 to ADFS but in this case we are going to use Azure AD (AAD) instead of ADFS.

This scenario involves idsrv3 as both an IDP to an ASP.NET MVC application and as a RP to AAD. Also I'm using the InMemory option.

So the authentication chain is:

RP --> IS --> AAD

IS is version 3. Everything is via WS-Fed.

I am doing this direct on idsrv3.

You should read the previous post to get the basics.

For this scenario, comment out the ADFS entry and add the AAD one as below. (don't be confused by the existing AAD entry - that's for OpenID Connect).

/*var adfs = new WsFederationAuthenticationOptions
{
    AuthenticationType = "adfs",
    Caption = "ADFS",
    SignInAsAuthenticationType = signInAsType,

    MetadataAddress = "https://adfs.local/federationmetadata/2007-06/federationmetadata.xml",
    Wtrealm = "urn:idsrv3rp"
};

app.UseWsFederationAuthentication(adfs);*/

var aadfed = new WsFederationAuthenticationOptions
{
    AuthenticationType = "aadfed",
    Caption = "Azure AD Fed",
    SignInAsAuthenticationType = signInAsType,

    MetadataAddress = "https://login.microsoftonline.com/xxx/federationmetadata/2007-06/federationmetadata.xml",
    Wtrealm = "https://localhost:44333/core/external/"
};

app.UseWsFederationAuthentication(aadfed);

Now we have to configure the AAD application. The steps to get your own AAD tenant etc. are extensively documented elsewhere and out of scope for this post.

In the AAD portal, in the AD tab on the left, click on "Applications" and click "Add" at the bottom.

The name can be anything.

Sign-On URL = https:/localhost:44333/core/external/
App ID URI =   https:/localhost:44333/core/external/
Reply URL =     https:/localhost:44333/core/external/

Then save the Application.

Now click on the application in the Application list and click on "View Endpoints" at the bottom.

Copy the "Federation Metadata Document" URL and paste it in the MetadataAddress in the code above.

Then run up the MVC application. This should redirect to the idsrv3 Login screen. Click the "Azure AD Fed" button, Authenticate on AAD. You should be redirected back to the application, click the Contacts tab and you should see the claims displayed.

Enjoy!

Friday, December 04, 2015

Misc : 500 posts milestone

Well there you are folks - 500 posts!!!

The first post was in March 2005 and they have been accumulating steadily since then.

According to the Blogger widget, these are the most popular posts:



but this differs slightly from the Blogger stats.



As you can see from the Labels, I've covered a vast area but I blog mainly in the Identity sphere these days.

The ADFS label is by far the most prolific with over 100 posts to date.

Here's to the next 500.

Enjoy!

IdentityServer : ASP.NET MVC application to idsrv3 to ADFS

This continues the series of blogs I've done on IdentityServer 3.

This scenario involves idsrv3 as both an IDP to an ASP.NET MVC application and as a RP to ADFS. Also I'm using the InMemory option.

So the authentication chain is:

RP --> IS --> ADFS

ADFS is ADFS ("AD FS") 3.0 and IS is version 3. Everything is via WS-Fed. This is being invoked by the Host.Web sample in idsrv3.

Refer to the documentation that has a WS-Federation section at the bottom.

You need two NuGet packages.

Microsoft.Owin.Security.WsFederation

IdentityServer3 - WS-Federation Plugin

Note that the Owin.Security.WsFederation plugin is implemented by Katana. It appears that the plugin only supports consuming metadata. It doesn't appear to support publishing it. This is for upstream federation.

The idsrv3 WS-Federation plugin is implemented by thinktecture. This does generate metadata. This is for downstream federation.

The MVC application is set up as per IdentityServer : Identity Server 3 as a WS-Federation IDP with an ASP.NET MVC application.

You need to change the following:
  • IdentityServerExtensions.cs in the Host.Configuration project

Here's the code for IdentityServerExtensions.cs:

using System.Collections.Generic;
using IdentityServer3.Core.Configuration;
using IdentityServer3.Core.Services;
using IdentityServer3.Host.Config;
using Microsoft.Owin.Security.Facebook;
using Microsoft.Owin.Security.Google;
using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.Owin.Security.Twitter;

using Microsoft.Owin.Security.WsFederation;

using IdentityServer3.WsFederation.Configuration;
using IdentityServer3.WsFederation.Models;
using IdentityServer3.WsFederation.Services;

namespace Owin
{
    public static class IdentityServerExtension
    {
        public static IAppBuilder UseIdentityServer(this IAppBuilder app)
        {
            // uncomment to enable HSTS headers for the host
            // see: https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security
            //app.UseHsts();

            app.Map("/core", coreApp =>
            {
                var factory = new IdentityServerServiceFactory()
                    .UseInMemoryUsers(Users.Get())
                    .UseInMemoryClients(Clients.Get())
                    .UseInMemoryScopes(Scopes.Get());

                factory.CustomGrantValidators.Add(
                    new Registration&lt;ICustomGrantValidator>(typeof(CustomGrantValidator)));
                factory.CustomGrantValidators.Add(
                    new Registration&lt;ICustomGrantValidator>(typeof(AnotherCustomGrantValidator)));

                factory.ConfigureClientStoreCache();
                factory.ConfigureScopeStoreCache();
                factory.ConfigureUserServiceCache();

                var idsrvOptions = new IdentityServerOptions
                {
                    SiteName = "IdentityServer3 plus WsFed IDP / RP",
                    
                    Factory = factory,
                    SigningCertificate = Cert.Load(),

                    PluginConfiguration = ConfigurePlugins,

                    AuthenticationOptions = new AuthenticationOptions
                    {
                        IdentityProviders = ConfigureIdentityProviders,
                        //EnablePostSignOutAutoRedirect = true
                    },

                    //LoggingOptions = new LoggingOptions
                    //{
                    //    EnableKatanaLogging = true
                    //},

                    //EventsOptions = new EventsOptions
                    //{
                    //    RaiseFailureEvents = true,
                    //    RaiseInformationEvents = true,
                    //    RaiseSuccessEvents = true,
                    //    RaiseErrorEvents = true
                    //}

                };

                coreApp.UseIdentityServer(idsrvOptions);
            });

            return app;
        }

        private static void ConfigurePlugins(IAppBuilder pluginApp, IdentityServerOptions options)
        {
            var wsFedOptions = new WsFederationPluginOptions(options);

            // data sources for in-memory services
            wsFedOptions.Factory.Register(new Registration&lt;IEnumerable&lt;RelyingParty>>(RelyingParties.Get()));
            wsFedOptions.Factory.RelyingPartyService = new Registration&lt;IRelyingPartyService>(typeof(InMemoryRelyingPartyService));

            pluginApp.UseWsFederationPlugin(wsFedOptions);
        }

        public static void ConfigureIdentityProviders(IAppBuilder app, string signInAsType)
        {
            var google = new GoogleOAuth2AuthenticationOptions
            {
                AuthenticationType = "Google",
                Caption = "Google",
                SignInAsAuthenticationType = signInAsType,

                ClientId = "767400843187-8boio83mb57ruogr9af9ut09fkg56b27.apps.googleusercontent.com",
                ClientSecret = "5fWcBT0udKY7_b6E3gEiJlze"
            };
            app.UseGoogleAuthentication(google);

            var fb = new FacebookAuthenticationOptions
            {
                AuthenticationType = "Facebook",
                Caption = "Facebook",
                SignInAsAuthenticationType = signInAsType,

                AppId = "676607329068058",
                AppSecret = "9d6ab75f921942e61fb43a9b1fc25c63"
            };
            app.UseFacebookAuthentication(fb);

            var twitter = new TwitterAuthenticationOptions
            {
                AuthenticationType = "Twitter",
                Caption = "Twitter",
                SignInAsAuthenticationType = signInAsType,

                ConsumerKey = "N8r8w7PIepwtZZwtH066kMlmq",
                ConsumerSecret = "df15L2x6kNI50E4PYcHS0ImBQlcGIt6huET8gQN41VFpUCwNjM"
            };
            app.UseTwitterAuthentication(twitter);

            var adfs = new WsFederationAuthenticationOptions
            {
                AuthenticationType = "adfs",
                Caption = "ADFS",
                SignInAsAuthenticationType = signInAsType,

                MetadataAddress = "https://adfs.local/federationmetadata/2007-06/federationmetadata.xml",
                Wtrealm = "urn:idsrv3rp"
            };
            app.UseWsFederationAuthentication(adfs);

            var aad = new OpenIdConnectAuthenticationOptions
            {
                AuthenticationType = "aad",
                Caption = "Azure AD",
                SignInAsAuthenticationType = signInAsType,

                Authority = "https://login.windows.net/4ca9cb4c-5e5f-4be9-b700-c532992a3705",
                ClientId = "65bbbda8-8b85-4c9d-81e9-1502330aacba",
                RedirectUri = "https://localhost:44333/core/aadcb"
            };

            app.UseOpenIdConnectAuthentication(aad);
        }
    }
}




For ADFS, you need to add idsrv3 as a RP.

You can get the metadata from https://localhost:44333/core/wsfed/metadata and import into ADFS in the normal fashion.

Once you have done this, you need to change the Endpoints tab in the RP from:

https://localhost:44333/core/wsfed

to

https://localhost:44333/core/external

and you need to add

urn:idsrv3rp

as an extra Identifier in the Identifier tab. This matches the Wtrealm in the code above

The reason you need to change the endpoint is because the two plugins are different (as discussed above). core/wsfed is for downstream, core/external is for upstream.

Now configure the following claims rules:


 


and


Then run up the MVC application. This should redirect to the idsrv3 Login screen. Click the ADFS button, Authenticate on ADFS. You should be redirected back to the application, click the Contacts tab and you should see the claims displayed.

Enjoy!