Добавить шифрование и подписание на сайт входа ADFS - PullRequest
0 голосов
/ 12 ноября 2018

2 января 2019 г. - добавлен дополнительный вопрос ниже

Я новичок в ADFS и занимаюсь разработкой сайта с именем входа в ADFS. Я получил базовое имя входа в ADFS, но без шифрования и подписи, и мне нужно добавить это к имени входа. Кто-нибудь знает, как это реализовать? и какой сертификат og я могу / должен использовать и как его получить?

Это мой код:

Default.aspx

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Button runat="server" ID="btnLogout" Text="Log out" OnClick="btnLogout_Click" /><br />
            <asp:Label runat="server" ID="lblInfo"></asp:Label>
        </div>
    </form>
</body>
</html>

Default.aspx.cs

using System;
using System.Threading;
using System.Web;
using System.Web.UI;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.User.Identity.IsAuthenticated)
        {
            lblInfo.Text += "<TABLE border=\"1\" Align=\"Center\" CellSpacing=\"15\" CellPadding = \"15\" >";
            lblInfo.Text += "<TR><TD>";
            lblInfo.Text += "<b>" + "Claim Type" + "</TD><TD>";
            lblInfo.Text += "<b>" + "Claim Value";
            lblInfo.Text += "</B></TD></TR>";

            foreach (var claim in (Thread.CurrentPrincipal.Identity as System.Security.Claims.ClaimsIdentity).Claims)
            {
                lblInfo.Text += "<TR><TD>";
                lblInfo.Text += claim.Type + "</TD><TD>";
                lblInfo.Text += claim.Value;
                lblInfo.Text += "</TD></TR>";
            }

            lblInfo.Text += "</TABLE>";
        }
    }

    protected void btnLogout_Click(object sender, EventArgs e)
    {
        var ctx = Request.GetOwinContext();
        var authenticationManager = ctx.Authentication;
        authenticationManager.SignOut();
    }
}

App_Code / RouteConfig.cs

using System.Web.Routing;
using Microsoft.AspNet.FriendlyUrls;

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        var settings = new FriendlyUrlSettings();
        settings.AutoRedirectMode = RedirectMode.Permanent;
        routes.EnableFriendlyUrls(settings);
    }
}

App_Code / Startup.cs

using Owin;

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }
}

App_Code / StartupAuth.cs

using System.Configuration;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.WsFederation;
using Owin;
using Microsoft.Owin.Extensions;

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

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

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseWsFederationAuthentication(
            new WsFederationAuthenticationOptions
            {
                Wtrealm = realm,
                MetadataAddress = adfsMetadata
            });

        app.UseStageMarker(PipelineStage.Authenticate);
    }
}

Web.config

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <!-- ADFS -->
    <add key="ida:ADFSMetadata" value="https://fs-test.OurServer.me/federationmetadata/2007-06/federationmetadata.xml" />
    <add key="ida:Wtrealm" value="https://MySite" />
    <!-- ADFS -->
  </appSettings>
    <system.web>
      <compilation debug="true" targetFramework="4.5"/>
      <httpRuntime targetFramework="4.5"/>
      <authorization>
        <deny users="?"/>
        <allow users="*"/>
      </authorization>
      <customErrors mode="Off"/>
    </system.web>
    <system.codedom>
        <compilers>
            <compiler language="c#;cs;csharp" extension=".cs"
                type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
            <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
                type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>
        </compilers>
    </system.codedom>
</configuration>

Обновление - 2 января 2019

Извините за поздний ответ Наконец-то у меня было время просмотреть все ваши ссылки, спасибо, они мне очень помогли, но я столкнулся с другой проблемой. Я думаю, что я добавил правильное шифрование, но теперь я получаю эту ошибку:

ID4175: издатель маркера безопасности не был распознан IssuerNameRegistry. Чтобы принять маркеры безопасности от этого эмитента, настройте IssuerNameRegistry на возвращение действительного имени для этого эмитента.

D: \ www_ADFS_SACCK_TEST_Simpel_med_encrypt_sign \ App_Code \ EncryptedSecurityTokenHandlerEx.cs Строка: 51

На многих сайтах упоминается, что именно отпечаток пальца вызывает проблему с некоторыми скрытыми символами в начале отпечатка, поэтому я набрал его вручную, но это не помогло.

Кто-нибудь знает, в чем может быть проблема?

Я изменил часть кода, теперь он выглядит так:

StartupAuth.cs

using System.Configuration;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.WsFederation;
using Owin;
using Microsoft.Owin.Extensions;
using System.Collections.ObjectModel;
using System.IdentityModel.Tokens;
using System.Collections.Generic;
using System.Threading;
using Microsoft.IdentityModel.Protocols;
using System.IdentityModel.Selectors;
using System.Security.Cryptography.X509Certificates;
using System;

public partial class Startup
{
    private static string realm = ConfigurationManager.AppSettings["ida:Wtrealm"];
    private static string _MetadataAddress = ConfigurationManager.AppSettings["ida:ADFSMetadata"];
    private static string _SignInAsAuthenticationType = "cookies";
    private const string SigningCertThumbprint = "d25xxxxxxxxxxxxxxxxxxxxxxxxxxxxf89";
  //private const string Issuer = "LOCAL AUTHORITY";
    private const string Issuer = "CN = testComp adfs";



    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
        });

        var audienceRestriction = new AudienceRestriction(AudienceUriMode.Always);
        audienceRestriction.AllowedAudienceUris.Add(new Uri(realm));

        var issuerRegistry = new ConfigurationBasedIssuerNameRegistry();
        issuerRegistry.AddTrustedIssuer(SigningCertThumbprint, Issuer);

        app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions(WsFederationAuthenticationDefaults.AuthenticationType)
        {
            Wtrealm = realm,
            MetadataAddress = _MetadataAddress,
            TokenValidationParameters = new TokenValidationParameters
            {
                AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
            },
            SecurityTokenHandlers = new SecurityTokenHandlerCollection
                    {
                        new EncryptedSecurityTokenHandlerEx(new X509CertificateStoreTokenResolver(StoreName.My, StoreLocation.LocalMachine)),
                        new SamlSecurityTokenHandlerEx
                        {
                            CertificateValidator = X509CertificateValidator.None,
                            Configuration = new SecurityTokenHandlerConfiguration()
                            {
                                AudienceRestriction = audienceRestriction,
                                IssuerNameRegistry = issuerRegistry
                            }
                        }
                    }
        });

        app.UseStageMarker(PipelineStage.Authenticate);

    }
}

Я также добавил еще два класса:

SamlSecurityTokenHandlerEx.cs

    using System.IdentityModel.Tokens;
    using System.IO;
    using System.Security.Claims;
    using System.Xml;

    public class SamlSecurityTokenHandlerEx : SamlSecurityTokenHandler, ISecurityTokenValidator
    {
        public override bool CanReadToken(string securityToken)
        {
            return base.CanReadToken(XmlReader.Create(new StringReader(securityToken)));
        }

        public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters,
                out SecurityToken validatedToken)
        {
            validatedToken = ReadToken(new XmlTextReader(new StringReader(securityToken)), Configuration.ServiceTokenResolver);
            return new ClaimsPrincipal(ValidateToken(validatedToken)); ;
        }

        public int MaximumTokenSizeInBytes { get; set; }
    }

EncryptedSecurityTokenHandlerEx.cs

using System;
using System.Collections.Generic;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Web;
using System.Xml;

public class EncryptedSecurityTokenHandlerEx : EncryptedSecurityTokenHandler, ISecurityTokenValidator
{
    public EncryptedSecurityTokenHandlerEx(SecurityTokenResolver securityTokenResolver)
    {
        Configuration = new SecurityTokenHandlerConfiguration
        {
            ServiceTokenResolver = securityTokenResolver
        };
    }

    public override bool CanReadToken(string securityToken)
    {
        return base.CanReadToken(new XmlTextReader(new StringReader(securityToken)));
    }

    public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
    {
        validatedToken = ReadToken(new XmlTextReader(new StringReader(securityToken)), Configuration.ServiceTokenResolver);
        if (ContainingCollection != null)
        {
            return new ClaimsPrincipal(ContainingCollection.ValidateToken(validatedToken));
    }
    return new ClaimsPrincipal(base.ValidateToken(validatedToken));
}

public int MaximumTokenSizeInBytes { get; set; }

}

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Это мое решение, и оно работает для меня. :)

Default.aspx

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Button runat="server" ID="btnLogout" Text="Log out" OnClick="btnLogout_Click" /><br />
            <asp:Label runat="server" ID="lblInfo"></asp:Label>
        </div>
    </form>
</body>
</html>

Default.aspx.cs

using System;
using System.Threading;
using System.Web;
using System.Web.UI;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.User.Identity.IsAuthenticated)
        {
            lblInfo.Text += "<TABLE border=\"1\" Align=\"Center\" CellSpacing=\"15\" CellPadding = \"15\" >";
            lblInfo.Text += "<TR><TD>";
            lblInfo.Text += "<b>" + "Claim Type" + "</TD><TD>";
            lblInfo.Text += "<b>" + "Claim Value";
            lblInfo.Text += "</B></TD></TR>";

            foreach (var claim in (Thread.CurrentPrincipal.Identity as System.Security.Claims.ClaimsIdentity).Claims)
            {
                lblInfo.Text += "<TR><TD>";
                lblInfo.Text += claim.Type + "</TD><TD>";
                lblInfo.Text += claim.Value;
                lblInfo.Text += "</TD></TR>";
            }

            lblInfo.Text += "</TABLE>";
        }
    }

    protected void btnLogout_Click(object sender, EventArgs e)
    {
        var ctx = Request.GetOwinContext();
        var authenticationManager = ctx.Authentication;
        authenticationManager.SignOut();
    }
}

App_Code / RouteConfig.cs

using System.Web.Routing;
using Microsoft.AspNet.FriendlyUrls;

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        var settings = new FriendlyUrlSettings();
        settings.AutoRedirectMode = RedirectMode.Permanent;
        routes.EnableFriendlyUrls(settings);
    }
}

App_Code / Startup.cs

using Owin;
using System;
using System.Configuration;
using System.IdentityModel.Metadata;
using System.IdentityModel.Services;
using System.ServiceModel.Security;
using System.Xml;

public partial class Startup
{
    private static readonly string ConfigAddress = AppDomain.CurrentDomain.BaseDirectory + "\\" + "Web.config";

    public void Configuration(IAppBuilder app)
    {
        string stsMetadataAddress = ComputeStsMetadataAddress();
        XmlDocument xmlConfig = new XmlDocument();
        XmlReader updatedConfigReader = null;

        using (XmlReader metadataReader = XmlReader.Create(stsMetadataAddress))
        {
            using (XmlReader configReader = XmlReader.Create(ConfigAddress))
            {
                MetadataSerializer serializer = new MetadataSerializer()
                {
                    CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust,
                };

                updatedConfigReader = FederationManagement.UpdateIdentityProviderTrustInfo(metadataReader, configReader, false, serializer);
            }
        }

        using (updatedConfigReader)
        {
            XmlDocument xmlUpdatedConfig = new XmlDocument();
            xmlUpdatedConfig.Load(updatedConfigReader);

            xmlUpdatedConfig.Save(ConfigAddress);
        }

    ConfigureAuth(app);
    }

    private static string ComputeStsMetadataAddress()
    {
        string stsIssuerAddress = FederatedAuthentication.FederationConfiguration.WsFederationConfiguration.Issuer;
        return new UriBuilder(stsIssuerAddress) { Path = ConfigurationManager.AppSettings["MetaDataPath"] }.Uri.AbsoluteUri;
    }
}

App_Code / StartupAuth.cs

using System.Configuration;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.WsFederation;
using Owin;
using Microsoft.Owin.Extensions;

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

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

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseWsFederationAuthentication(
            new WsFederationAuthenticationOptions
            {
                Wtrealm = realm,
                MetadataAddress = adfsMetadata
            });

        app.UseStageMarker(PipelineStage.Authenticate);
    }
}

Web.config

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
  </configSections>
  <appSettings>
    <add key="UseADFS" value="True"/>
    <add key="ida:ADFSMetadata" value="https://fs.ourserver.com/federationmetadata/2007-06/federationmetadata.xml" />
<add key="ida:Wtrealm" value="https://example" />
<add key="MetaDataPath" value="federationmetadata/2007-06/federationmetadata.xml" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5">
      <assemblies>
        <add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
      </assemblies>
    </compilation>
    <httpRuntime targetFramework="4.5" />
    <authorization>
      <deny users="?" />
      <allow users="*" />
    </authorization>
    <customErrors mode="Off" />
  </system.web>
  <system.webServer>
    <modules>
      <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
      <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
    </modules>
  </system.webServer>
  <system.identityModel>
    <identityConfiguration>
      <audienceUris>
        <add value="https://example" />
      </audienceUris>
      <certificateValidation certificateValidationMode="PeerOrChainTrust" />
      <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <trustedIssuers>
          <add thumbprint="BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1" name="http://fs.ourserver.com/adfs/services/trust" />
    </trustedIssuers>
  </issuerNameRegistry>
</identityConfiguration>
  </system.identityModel>
  <system.identityModel.services>
<federationConfiguration>
  <wsFederation passiveRedirectEnabled="true" issuer="https://fs.ourserver.com/adfs/ls/" realm="https://example" requireHttps="false" />
  <cookieHandler requireSsl="false" />
  <serviceCertificate>
    <certificateReference x509FindType="FindByThumbprint" findValue="DXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX9" storeLocation="LocalMachine" />
  </serviceCertificate>
</federationConfiguration>
  </system.identityModel.services>
  <system.codedom>
<compilers>
  <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
  <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
</compilers>
  </system.codedom>
  <connectionStrings>
  </connectionStrings>
</configuration>
0 голосов
/ 12 ноября 2018

На стороне ADFS вы просто добавляете сертификаты в мастер на вкладках подписи и шифрования.

На клиенте, вот хороший пример .

Для тестирования вы можете использовать самозаверяющий сертификат .

Чтобы двигаться дальше, вам нужно купить один, например, у. GoDaddy или получить бесплатный от "Let's Encrypt".

Хорошая документация по разработке ADFS здесь .

Пример использования стека WS-Fed OWIN .

или более старый образец, использующий WIF .

Обратите внимание, что это для Azure AD, но принципы те же.

...