Azure 通过多个应用程序使用ACS进行单点登录
简单单点登录问题 我有两个MVC4应用程序:Azure 通过多个应用程序使用ACS进行单点登录,azure,asp.net-mvc-4,single-sign-on,acs,Azure,Asp.net Mvc 4,Single Sign On,Acs,简单单点登录问题 我有两个MVC4应用程序: **1**- http://localhost/BikeShop ACS Relying Party: - Name: **BikeShop** - Return Url: **http://localhost/BikeShop** - Token Format: **SAML 2.0** **2**- http://localhost/BikePartsShop ACS Relying Party: -
**1**- http://localhost/BikeShop
ACS Relying Party:
- Name: **BikeShop**
- Return Url: **http://localhost/BikeShop**
- Token Format: **SAML 2.0**
**2**- http://localhost/BikePartsShop
ACS Relying Party:
- Name: **BikePartsShop**
- Return Url: **http://localhost/BikePartsShop**
- Token Format: **SAML 2.0**
我的场景 我访问BikeShop并显示ACS登录页面,然后选择我的身份 我现在可以在BikeShop上做些事情了 然后,我访问BikePartsShop,并显示ACS登录页面,我可以选择我的身份
我必须具备的情景 我访问BikeShop并显示ACS登录页面,然后选择我的身份 我现在可以在BikeShop上做些事情了 然后我访问BikePartsShop,ACS授权相同的身份 在BikeShop中使用,无需用户进一步干预
有人实现过这个场景吗
致以最良好的问候,谢谢 您可以使用ACS管理服务为同一依赖方配置多个回复地址。有关如何添加RP的详细信息,请参阅。从链接的代码示例中,注册更多地址,如下所示:
RelyingParty relyingParty = new RelyingParty()
{
Name = "BikeShop",
AsymmetricTokenEncryptionRequired = false,
TokenType = "SAML_2_0",
TokenLifetime = 3600
};
svc.AddToRelyingParties(relyingParty);
RelyingPartyAddress realm = new RelyingPartyAddress()
{
Address = "http://localhost/",
EndpointType = "Realm"
};
RelyingPartyAddress replyAddress1 = new RelyingPartyAddress()
{
Address = "http://localhost/BikeShop",
EndpointType = "Reply"
};
RelyingPartyAddress replyAddress2 = new RelyingPartyAddress()
{
Address = "http://localhost/BikePartsShop",
EndpointType = "Reply"
};
svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", realmAddress);
svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", replyAddress1);
svc.AddRelatedObject(relyingParty, "RelyingPartyAddresses", replyAddress2);
svc.SaveChanges(SaveChangesOptions.Batch);
如果您能找出如何记住上次使用的身份提供程序,请尝试使用此代码以帮助您转发到特定的身份提供程序。应存储最后一次登录,以便您将302自动返回到应用程序
public IdentityProvider GetIdentityProvider(string identityProviderName, string realm , string audienceUri )
{
// acs config parameters
string acsNamespace = ConfigurationManager.AppSettings["ida:Namespace"];
realm = realm ?? Uri.EscapeDataString(ConfigurationManager.AppSettings["ida:Realm"]);
audienceUri = audienceUri ?? ConfigurationManager.AppSettings["ida:AudienceUri"];
string returnPath = Uri.EscapeDataString("/home/index");
var newReplyTo =
Uri.EscapeDataString(audienceUri.Replace(new Uri(audienceUri).Authority,
HttpContext.Current.Request.Url.Authority));
// retrieve current identity providers
string idpDiscoveryUrl = string.Format("{0}v2/metadata/IdentityProviders.js?protocol=wsfederation&realm={1}&reply_to={2}&context=rm%3d0%26id%3dpassive%26ru%3d{3}&request_id=&version=1.0", acsNamespace, realm, newReplyTo, returnPath);
string response = null;
using (var client = new WebClient()) {
response = client.DownloadString(idpDiscoveryUrl);
}
List<IdentityProvider> identityProviders = JsonConvert.DeserializeObject<List<IdentityProvider>>(response);
// lookup provider for tenant
var identityProvider = identityProviders.Where(i => i.Name == identityProviderName).FirstOrDefault() ?? new IdentityProvider();
return identityProvider;
}
public IdentityProvider GetIdentityProvider(字符串identityProviderName、字符串领域、字符串audenceUri)
{
//acs配置参数
字符串acsNamespace=ConfigurationManager.AppSettings[“ida:Namespace”];
realm=realm??Uri.EscapeDataString(ConfigurationManager.AppSettings[“ida:realm”]);
audienceUri=audienceUri??ConfigurationManager.AppSettings[“ida:audienceUri”];
字符串returnPath=Uri.EscapeDataString(“/home/index”);
var newReplyTo=
expressedatastring(audenceUri.Replace)(新Uri(audenceUri.Authority),
HttpContext.Current.Request.Url.Authority);
//检索当前身份提供程序
string idpDiscoveryUrl=string.Format(“{0}v2/metadata/IdentityProviders.js?protocol=wsfederation&realm={1}&reply_to={2}&context=rm%3d0%26id%3dpassive%26ru%3d{3}&request_id=&version=1.0”,acsNamespace,realm,newReplyTo,returnPath);
字符串响应=null;
使用(var client=new WebClient()){
response=client.DownloadString(idpDiscoveryUrl);
}
List identityProviders=JsonConvert.DeserializeObject(响应);
//租户的查找提供程序
var identityProvider=identityProviders.Where(i=>i.Name==identityProviderName).FirstOrDefault()??new identityProvider();
返回标识提供程序;
}
BikeShop和BikePartsShop应该是一个RP而不是两个RP吗?一个RP可以支持多个应答地址,这将允许在两个RP上使用相同的令牌。如何使用ACS实现这一点。ACS中继方只能配置一个应答地址(返回Url),这不是真的,ACS支持配置任意多个应答地址。我会发布一个答案。我会尝试那个解决方案。非常感谢。在实现了所有代码并能够成功部署和运行它之后,创建了ACS依赖方,添加了身份提供者,并配置了回复地址。两个应用程序的所有规则均正确执行。这些主张正在得到正确的解释。但是,如果不显示ACS的“登录”屏幕,我仍然无法在站点之间进行更改,您可以在其中选择要使用的身份提供程序。是否在web.config中的同一WSFederationAuthenticationModule和SessionAuthenticationModule下配置了这两个身份提供程序?听起来好像一个站点没有看到另一个站点的cookie。它是相同的WSFederationAuthenticationModule和SessionAuthenticationModule,具有相同的领域、ACS中相同的依赖方以及相同的信任、受众URI等。我甚至尝试在cookieHandler元素中使用相同的cookie名称,但只是为了在第二个站点认证上使用第一个cookie。我想这些cookie不能放在同一个ASP.NET网站下?如果不是,这听起来像是一个WIF问题,我不知道答案,可能值得作为一个单独的问题在“WIF”下标记。你的问题是,你有两个相同领域的网站,你希望他们能够共享cookie;我不确定这是否可能。另一种解决方案是在ACS和保存令牌的RPs之间添加RP-STS。