Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Single Sign-On (ADFS) in ASP.NET MVC

FYI: see update 12-FEB-2019

I have created an ASP.NET MVC application (using Visual Studio) and attempted to get it to handle SSO using an Active Directory Federated Server. Note, this is not using Azure.

So, the first step works - I navigate to my login page and there's a button to allow me to log onto another service ["Federation"]. This launches the ADFS web page where I enter my credentials, but on returning to my website, I get the following error:

IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'.

Exception Details: Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'.

Evidently, I've not got this set up right....so need to know what I'm missing...

Here is my (cut down) code:

Startup.Auth.cs

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);    

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
        });

        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

        app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
        {
            MetadataAddress = "https://adfs.Mydomain.com/FederationMetadata/2007-06/FederationMetadata.xml",
            Wtrealm = "https://myWebServer/myWebApplication"
        });
    }

    private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
    {
        return true; // Our "TEST" ADFS has a fake certficate, so we don't want to validate it.
    }
}

Sections in the Web.Config

  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />

    <add key="ClaimsNameIdentifier" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" />
    <add key="ClaimsUPNIdentifier" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" />
    <add key="ClaimsEmailIdentifier" value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" />
  </appSettings>

  <system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.7.1" />
    <httpRuntime targetFramework="4.7.1" />
  </system.web>

(Note: in the authentication element above, intellisense gave me "Federated" as a option, but this results in a compile error).

One helpful resource was alligatortek, but that didn't really fill in all the pieces. There are others resources that seem close, but not specific enough.

UPDATE 12-FEB-2019

Based on comments below, I was advised to instead follow Vittorio Bertocci's post which uses the "On-Premesis" option (this is pretty much identical to Rober Finch's post). The resulting code is a bit different (see below) but the result is still the same.

Startup.Auth.cs

public partial class Startup
{
    private static readonly string realm = ConfigurationManager.AppSettings["ida:Wtrealm"];
    private static readonly string adfsMetadata = ConfigurationManager.AppSettings["ida:ADFSMetadata"];

    /// <summary>
    ///     Configures the authentication.
    /// </summary>
    /// <param name="app">The current application.</param>
    public void ConfigureAuth(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        ServicePointManager.ServerCertificateValidationCallback = this.ValidateServerCertificate;
        app.UseWsFederationAuthentication(
            new WsFederationAuthenticationOptions
            {
                Wtrealm = Startup.realm,
                MetadataAddress = Startup.adfsMetadata
            });
    }

    private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
    {
        return true; // Skips certificate validation as using a temp certificate.
    }
}

Sections in the Web.Config

<appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="ida:ADFSMetadata" value="https://adfs.Mydomain.com/FederationMetadata/2007-06/FederationMetadata.xml" />
    <add key="ida:Wtrealm" value="https://myWebServer/myWebApplication" />
</appSettings>
like image 435
DrGriff Avatar asked Oct 22 '25 05:10

DrGriff


2 Answers

By far the easiest way to do this is via the "On-Premises" option in VS.

like image 135
rbrayb Avatar answered Oct 23 '25 21:10

rbrayb


Finally solved this.

In the Startup.Auth.cs file, I temporarily added the following line to the ConfigAuth(...) method:

Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;

This then showed me that I had to add a trailing slash to the "Wtrealm" value the web.config entry

So from:

<add key="ida:Wtrealm" value="https://myWebServer/myWebApplication" />

to :

<add key="ida:Wtrealm" value="https://myWebServer/myWebApplication/" />
like image 21
DrGriff Avatar answered Oct 23 '25 20:10

DrGriff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!