Azure 通过多个应用程序使用ACS进行单点登录

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: -

简单单点登录问题

我有两个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:

 - 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。