GithubHelp home page GithubHelp logo

ehtick / abc.identityserver4.saml2 Goto Github PK

View Code? Open in Web Editor NEW

This project forked from abc-software/abc.identityserver4.saml2

0.0 0.0 0.0 2.71 MB

Implementation SAML2 IdP support for IdentityServer4

License: Apache License 2.0

C# 100.00%

abc.identityserver4.saml2's Introduction

Abc.IdentityServer4.Saml2

Overview

Implementation SAML2 IdP support for IdentityServer4 with .NET core.

This is useful for connecting older relying parties to IdentityServer4.

.NET Support

The underlying SAML2 classes use .NET Core.

SAML2 endpoint

The SAML2 endpoints is implemented via an IdentityServer4.Hosting.IEndpointHanlder. Endpoint ~/saml2/metadata returns SAML2 metadata, ~/saml2 process SAML2 sing-in and sign-out requests. This endpoints handles the SAML2P protocol requests and redirects the user to the login page if needed.

The login page will then use the normal return URL mechanism to redirect back to the SAML2 endpoint to create the protocol response.

Configuration

For most parts, the SAML2 endpoint can use the standard IdentityServer4 client configuration for relying parties. But there are also options available for setting SAML2 specific options.

Defaults

You can configure global defaults in the Saml2SPOptions class, e.g.:

  • default hashing and digest algorithms
  • default SAML name identifier format
  • default encryption and keywrap algorithms
  • default mappings from "short" claim types to WS-* claim types
  • specify Saml2SecurityTokenHandler

Relying party configuration

The following client settings are used by the SAML2 endpoint:

public static IEnumerable<Client> GetClients()
{
    return new[]
    {
        new Client
        {
            ClientId = "urn:owinrp", // entityId identifier
            ProtocolType = ProtocolTypes.Saml2p, // must be set to SAML2

            RedirectUris = { "https://localhost:44334/Saml2/Acs" }, // reply URL
            PostLogoutRedirectUris = { "https://localhost:44334/" }, 
            FrontChannelLogoutUri = "https://localhost:44334/Saml2/Acs",
            AccessTokenLifetime = 36000, // lifetime of SAML2 token

            AllowedScopes = { "openid", "profile" }
        },
        new Client
        {
            ClientId = "urn:aspnetcorerp",
            ProtocolType = ProtocolTypes.Saml2p,

            RedirectUris = { "https://localhost:44302/Auth/AssertionConsumerService" },
            PostLogoutRedirectUris = { "https://localhost:44302/Auth/PostLogout" },
            FrontChannelLogoutUri = "https://localhost:44302/Auth/Logout",
            AccessTokenLifetime = 36000,

            AllowedScopes = { "openid", "profile" }
        },
        new Client
        {
            ClientId = "urn:aspnetwebapprp",
            ProtocolType = ProtocolTypes.Saml2p,

            RedirectUris = { "https://localhost:44314/Default.aspx" },
            PostLogoutRedirectUris = { "https://localhost:44314/Default.aspx" },
            FrontChannelLogoutUri = "https://localhost:44314/Default.aspx",
            AccessTokenLifetime = 36000,

            AllowedScopes = { "openid", "profile" }
        },
    };
}

SAML2 specific relying party settings

If you want to deviate from the global defaults (e.g. set a different token type or claim mapping) for a specific relying party, you can define a RelyingParty object that uses the same realm name as the client ID used above.

This sample contains an in-memory relying party store that you can use to make these relying party specific settings available to the SAML2 engine (using the AddInMemoryRelyingParty extension method). Otherwise, if you want to use your own store, you will need an implementation of IRelyingPartyStore.

Configuring IdentityServer

This repo contains an extension method for the IdentityServer builder object to register all the necessary services in DI, e.g.:

services.AddDistributedMemoryCache();
services.AddIdentityServer()
    .AddSigningCredential(cert)
    .AddInMemoryIdentityResources(Config.GetIdentityResources())
    .AddInMemoryApiResources(Config.GetApiResources())
    .AddInMemoryClients(Config.GetClients())
    .AddTestUsers(TestUsers.Users)
    .AddSaml2()
    .AddAuthorizationParametersMessageStore<DistributedCacheAuthorizationParametersMessageStore>()
    .AddInMemoryRelyingParties(Config.GetRelyingParties());

Enable encrypted SAML2.0 token

Add to project Abc.IdentityModel.Tokens.Saml via nuget and change SecurityTokenHandlers, e.g.:

builder.AddSaml2(options => {
    // Add encrypted SAML2.0 tokens support
    options.SecurityTokenHandler = new Abc.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler()
    };
});

Connecting a relying party to the SAML2 endpoint

Using .NET Core

Use the .NET Core SAML2 middleware to point to the SAML2 endpoint, e.g.:

public void ConfigureServices(IServiceCollection services) 
{
        services.AddRazorPages();

        services.Configure<Saml2Configuration>(saml2Configuration => {
            saml2Configuration.Issuer = Configuration["saml2:issuer"];
            saml2Configuration.AllowedAudienceUris.Add(saml2Configuration.Issuer);
            saml2Configuration.SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
            saml2Configuration.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.ChainTrust;
            // !!! REMOVE for production
            saml2Configuration.RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck;
            // !!! for TEST only
            saml2Configuration.SaveBootstrapContext = true;

            var entityDescriptor = new EntityDescriptor();
            entityDescriptor.ReadIdPSsoDescriptorFromUrl(new Uri(Configuration["saml2:metadata"]));
            if (entityDescriptor.IdPSsoDescriptor != null) {
                saml2Configuration.SingleSignOnDestination = entityDescriptor.IdPSsoDescriptor.SingleSignOnServices.First().Location;
                saml2Configuration.SingleLogoutDestination = entityDescriptor.IdPSsoDescriptor.SingleLogoutServices.First().Location;
                saml2Configuration.SignatureValidationCertificates.AddRange(entityDescriptor.IdPSsoDescriptor.SigningCertificates);
            }
            else {
                throw new Exception("IdPSsoDescriptor not loaded from metadata.");
            }

            // !!! for ADFS
            saml2Configuration.SignAuthnRequest = true;

            var certPath = Path.Combine(Directory.GetCurrentDirectory(), "saml2.sample.pfx");
            if (!File.Exists(certPath)) {
                throw new InvalidOperationException($"{certPath} not found");
            }

            saml2Configuration.SigningCertificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(certPath, "abc", System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.MachineKeySet);
        });

        services.AddSaml2();
}

Using Katana

Use the Katana SAML2 middleware to point to the SAML2 endpoint, e.g.:

public void Configuration(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseCookieAuthentication(new CookieAuthenticationOptions() {
        CookiePath = HostingEnvironment.ApplicationVirtualPath,
        CookieSameSite = Microsoft.Owin.SameSiteMode.None, 
    });

    app.UseSaml2Authentication(CreateSaml2Options())
}

private static Saml2AuthenticationOptions CreateSaml2Options() {
    var spOptions = new SPOptions {
        EntityId = new EntityId(realm),
        AuthenticateRequestSigningBehavior = SigningBehavior.IfIdpWantAuthnRequestsSigned,
        ReturnUrl = new Uri(System.Web.VirtualPathUtility.ToAbsolute("~/Home"), UriKind.Relative),
    };

    spOptions.ServiceCertificates.Add(new X509Certificate2(
        AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/App_Data/saml2.sample.pfx", "abc"));

    var saml2Options = new Saml2AuthenticationOptions(false) {
        SPOptions = spOptions
    };

    var ed = MetadataLoader.LoadIdp(adfsMetadata, false);

    var idp = new IdentityProvider(ed.EntityId, spOptions) {
        AllowUnsolicitedAuthnResponse = true,
    };
            
    idp.ReadMetadata(ed);
    saml2Options.IdentityProviders.Add(idp);

    return saml2Options;
}

Using ASP.NET WebForms

Use the WebForms SAML2 module to point to the SAML2 endpoint, e.g.:

<configuration>
  <configSections>
    <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <section name="microsoft.identityModel.saml" type="Microsoft.IdentityModel.Web.Configuration.MicrosoftIdentityModelSamlSection, Microsoft.IdentityModel.Protocols" />
  </configSections>
  <system.webServer>
    <modules>
        <remove name="FormsAuthentication" />
        <add name="Saml2AuthenticationModule" type="ServiceProvider.MySaml2AuthenticationModule" />
        <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule" />
    </modules>
  </system.webServer>
  <microsoft.identityModel>
    <service>
      <!-- The set of audience URIs. This should match the entityID specified in metadata\homerealmdiscovery.xml. -->
      <audienceUris>
        <add value="urn:sample:saml2:fx" />
      </audienceUris>
      <!-- Enable encrypted tokens -->
      <serviceCertificate>
        <certificateReference x509FindType="FindBySubjectDistinguishedName" findValue="CN=localhost" storeLocation="LocalMachine" storeName="My"/>
      </serviceCertificate>
      <!--!!! Remove in production -->
      <certificateValidation certificateValidationMode="None" />
      <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry">
        <!-- The set of trusted issuers.  This should match the entityIDs and thumbprints of signing certificates 
             specified in metadata\identityprovider.xml. -->
        <trustedIssuers>
          <add thumbprint="6b7acc520305bfdb4f7252daeb2177cc091faae1" name="IdentityServer.Saml2" />
        </trustedIssuers>
      </issuerNameRegistry>
      <!-- The resolver to use when finding this service's signing and encrypting certificates. -->
      <serviceTokenResolver type="Samples.Saml.Utilities.SampleServiceProviderSecurityTokenResolver" />
      <!-- Enable saveBootstrapTokens so the token visualizer can show the raw SAML assertion. -->
      <securityTokenHandlers>
        <securityTokenHandlerConfiguration saveBootstrapTokens="true">
        </securityTokenHandlerConfiguration>
      </securityTokenHandlers>
      <federatedAuthentication>
        <cookieHandler requireSsl="true" />
      </federatedAuthentication>
    </service>
  </microsoft.identityModel>
</configuration>

abc.identityserver4.saml2's People

Contributors

gekiss avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.