c# - 没有实体 ID 为 "http://stubidp.kentor.se/Metadata"的 Idp 在 Kentor 身份验证服务中发现错误

标签 c# owin kentor-authservices

我们需要启用 SAML SSO 登录到我的应用程序。我的应用程序是 Angular JS + Asp.Net Web API 解决方案。我的应用程序已经使用 Owin Bearer Authentication 作为授权模型。

启用 Saml SSO 我正在试验 Kentor Auth Services .但是当 Idp 调用我的 webapi 时,我遇到了一个问题。 kentor 服务抛出 The given key was not present in the dictionary. 错误。我正在使用 http://stubidp.kentor.se/测试实现。下面是我在启动类(class)中的 Saml 配置

public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);
            ConfigureOAuth(app);

            var config = new HttpConfiguration();
            WebApiConfig.Register(config);
            app.UseWebApi(config);

            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            GlobalConfiguration.Configuration.MessageHandlers.Add(new CachingHandler(GlobalConfiguration.Configuration));
        }
        public void ConfigureOAuth(IAppBuilder app)
        {
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            var oAuthServerOptions = new OAuthAuthorizationServerOptions
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/Auth/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new JobPulseAuthorizationServerProvider()
            };
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    // Enables the application to validate the security stamp when the user logs in.
                    // This is a security feature which is used when you change a password or add an external login to your account.  
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                            validateInterval: TimeSpan.FromMinutes(30),
                            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager, DefaultAuthenticationTypes.ExternalCookie))
                }
            });
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Token Generation
            //app.UseOAuthAuthorizationServer(oAuthServerOptions);
            //app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
            app.UseKentorAuthServicesAuthentication(CreateAuthServicesOptions());
        }

        private static KentorAuthServicesAuthenticationOptions CreateAuthServicesOptions()
        {
            var spOptions = GetServiceProviderOptions();
            var authServicesOptions = new KentorAuthServicesAuthenticationOptions(false)
            {
                SPOptions = spOptions
            };

            var idp = new IdentityProvider(new EntityId("~/App_Data/KentorIDPMetadata.xml"), spOptions)
            {
                AllowUnsolicitedAuthnResponse = true,
                Binding = Saml2BindingType.HttpRedirect,
                SingleSignOnServiceUrl = new Uri("http://stubidp.kentor.se/")
            };

            idp.SigningKeys.AddConfiguredKey(
                    new X509Certificate2(fileName: HostingEnvironment.MapPath(
                                    "~/App_Data/Kentor.AuthServices.StubIdp.cer")));

            authServicesOptions.IdentityProviders.Add(idp);

            return authServicesOptions;
        }

        private static SPOptions GetServiceProviderOptions()
        {
            var cultureInfo = CultureInfo.GetCultureInfo("en-US");
            var organization = new Organization
            {
                Names = { new LocalizedName("Kentor", cultureInfo) },
                DisplayNames = { new LocalizedName("Kentor IT AB", cultureInfo) },
                Urls = { new LocalizedUri(new Uri("http://www.kentor.se"), cultureInfo) }
            };
            var spOptions = new SPOptions
            {
                EntityId = new EntityId("http://localhost:53390/AuthServices/acs"),
                ReturnUrl = new Uri("http://localhost:53390/Account/ExternalLoginCallback"),
                Organization = organization
            };
            spOptions.Contacts.Add(new ContactPerson
            {
                Type = ContactType.Technical,
                EmailAddresses = { "authservices@example.com" }
            });

            spOptions.Contacts.Add(new ContactPerson
            {
                Type = ContactType.Support,
                EmailAddresses = { "support@example.com" }
            });
            var attributeConsumingService = new AttributeConsumingService("AuthServices")
            {
                IsDefault = true,
                RequestedAttributes =
                {
                    new RequestedAttribute("urn:someName")
                    {
                        FriendlyName = "Some Name",
                        IsRequired = true,
                        NameFormat = RequestedAttribute.AttributeNameFormatUri
                    },
                    new RequestedAttribute("Minimal")
                }
            };
            spOptions.AttributeConsumingServices.Add(attributeConsumingService);

            spOptions.ServiceCertificates.Add(new X509Certificate2(
                    AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/App_Data/Kentor.AuthServices.Tests.pfx"));

            return spOptions;
        }

    }

错误的堆栈跟踪

[KeyNotFoundException: The given key was not present in the dictionary.]
   System.Collections.Generic.Dictionary`2.get_Item(TKey key) +11759657
   Kentor.AuthServices.Configuration.IdentityProviderDictionary.get_Item(EntityId entityId) +155

[KeyNotFoundException: No Idp with entity id "http://stubidp.kentor.se/Metadata" found.]
   Kentor.AuthServices.Configuration.IdentityProviderDictionary.get_Item(EntityId entityId) +291
   Kentor.AuthServices.Saml2P.Saml2Response.CheckIfUnsolicitedIsAllowed(IOptions options) +108
   Kentor.AuthServices.Saml2P.Saml2Response.Validate(IOptions options) +37
   Kentor.AuthServices.Saml2P.<CreateClaims>d__53.MoveNext() +170
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +381

能否请您告诉我为什么 Kentor 无法获取元数据?

最佳答案

您将实体 ID 与元数据路径混淆了。元数据暴露在作为实体 ID 的地址,但如果您将元数据放在本地,则需要将它们分开。

var idp = new IdentityProvider(new EntityId("http://stubidp.kentor.se/Metadata"), spOptions)
{
  MetadataLocation = ""~/App_Data/KentorIDPMetadata.xml"
  AllowUnsolicitedAuthnResponse = true,
  // No need to add these if metadata is read.
  // Binding = Saml2BindingType.HttpRedirect,
  // SingleSignOnServiceUrl = new Uri("http://stubidp.kentor.se/")
};

另一种更简单的方法是直接从 idp 加载元数据:

var idp = new IdentityProvider(new EntityId("http://stubidp.kentor.se/Metadata"), spOptions)
{
  LoadMetadata = true,
  AllowUnsolicitedAuthnResponse = true,
};

关于c# - 没有实体 ID 为 "http://stubidp.kentor.se/Metadata"的 Idp 在 Kentor 身份验证服务中发现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39853989/

相关文章:

c# - 使用 Comparer 按不同字段对 C# 中的 IEnumerable 进行排序

c# - 将 javascript 与 asp.net 连接起来

c# - Active Directory 检查用户是否登录

c# - 尝试在带有 OWIN 的 ASP.NET MVC 站点中使用简单注入(inject)器

c# - 获得新的 access_token 后如何更新我的 cookie?

c# - "The specified network password is not correct"在没有密码的证书上,仅在实时服务器上

c# - 类型或命名空间 'Timers' 命名空间 'System' 中不存在名称

cors - 当与 ASP.NET Web Api 2.0 一起使用时,Microsoft.Owin.Cors 中间件有什么作用?

c# - KentorAuth 签名请求 XML