我们要求启用SAML SSO登录我的应用程序。我的应用程序是Angular JS + Asp.Net Web API解决方案。我的应用程序已经使用Owin Bearer Authentication作为授权模型。
启用Saml SSO我正在试验Kentor Auth Services。但是,当Idp称我的webapi时,我正面临着一个问题。 kentor服务抛出字典中没有给定的密钥。错误。我使用http://stubidp.kentor.se/来测试实现。以下是我在启动课程中的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无法获取元数据?
答案 0 :(得分:5)
您将实体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,
};