首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用IdentityServer3的Sitecore 9联邦认证,无止境循环

使用IdentityServer3的Sitecore 9联邦认证,无止境循环
EN

Stack Overflow用户
提问于 2017-11-21 04:54:16
回答 1查看 2.3K关注 0票数 7

我一直在努力让联邦身份验证使用IdentityServer 3作为IDP与Sitecore 9合作。我遵循了http://blog.baslijten.com/enable-federated-authentication-and-configure-auth0-as-an-identity-provider-in-sitecore-9-0/ for Auth0中的示例,并将其转换为IDS3。但我所经历的是国内流离失所者和塞特罗雷之间的无穷无尽的循环。

在进行身份验证时,IdentityServer 3似乎会重定向回Sitecore,后者无法将身份验证转换为cookie。我只剩下一个.nonce曲奇。Sitecore没有看到经过身份验证的用户,而是重定向到IDP,这种情况一直持续到我停止进程为止。

我的IdentityProviderProcessor (带有虚拟值):

代码语言:javascript
运行
复制
using System.Threading.Tasks;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using Sitecore.Diagnostics;
using Sitecore.Owin.Authentication.Configuration;
using Sitecore.Owin.Authentication.Pipelines.IdentityProviders;
using Sitecore.Owin.Authentication.Services;

namespace xx.xxxx.SC.Foundation.Authentication
{
    public class IdentityProviderProcessor : IdentityProvidersProcessor
    {
        public IdentityProviderProcessor(FederatedAuthenticationConfiguration federatedAuthenticationConfiguration) : base(federatedAuthenticationConfiguration)
        {

        }

        /// <summary>
        /// Identityprovidr name. Has to match the configuration
        /// </summary>
        protected override string IdentityProviderName
        {
            get { return "ids3"; }
        }

        protected override void ProcessCore(IdentityProvidersArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            IdentityProvider identityProvider = this.GetIdentityProvider();
            string authenticationType = this.GetAuthenticationType();

            args.App.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies"
            });

            args.App.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                Authority = "xxxx",
                ClientId = "xxxx",
                Scope = "openid profile xxxx",
                RedirectUri = "xxxx",
                ResponseType = "id_token token",
                SignInAsAuthenticationType = "Cookies",
                UseTokenLifetime = false,
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    SecurityTokenValidated = (context) =>
                    {
                        var identity = context.AuthenticationTicket.Identity;

                        foreach (Transformation current in identityProvider.Transformations)
                        {
                            current.Transform(identity, new TransformationContext(FederatedAuthenticationConfiguration, identityProvider));
                        }

                        var virtualUser = Sitecore.Security.Authentication.AuthenticationManager.BuildVirtualUser("xxxx\\user@domain.com", true);

                        // You can add roles to the Virtual user
                       virtualUser.Roles.Add(Sitecore.Security.Accounts.Role.FromName("extranet\\MyRole"));

                        // You can even work with the profile if you wish
                        virtualUser.Profile.SetCustomProperty("CustomProperty", "12345");
                        virtualUser.Profile.Email = "user@domain.com";
                        virtualUser.Profile.Name = "My User";

                        // Login the virtual user
                        Sitecore.Security.Authentication.AuthenticationManager.LoginVirtualUser(virtualUser);

                        return Task.FromResult(0);
                    },
                },
            });
        }
    }
}

我的配置文件:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore role:require="Standalone or ContentDelivery or ContentManagement">

    <pipelines>
      <owin.identityProviders>
        <!-- Processors for coniguring providers. Each provider must have its own processor-->
        <processor type="xx.xxxx.SC.Foundation.Authentication.IdentityProviderProcessor, xx.xxxx.SC.Foundation.Authentication" resolve="true" />
      </owin.identityProviders>
    </pipelines>

    <federatedAuthentication type="Sitecore.Owin.Authentication.Configuration.FederatedAuthenticationConfiguration, Sitecore.Owin.Authentication">
      <!--Provider mappings to sites-->
      <identityProvidersPerSites hint="list:AddIdentityProvidersPerSites">
        <!--The list of providers assigned to all sites-->
        <mapEntry name="all sites" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication">
          <sites hint="list">
            <sites hint="list">
              <site>modules_website</site>
              <site>website</site>
            </sites>
          </sites>
          <identityProviders hint="list:AddIdentityProvider">
            <identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='ids3']" />
          </identityProviders>
          <externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication">

            <param desc="isPersistentUser">false</param>

          </externalUserBuilder>
        </mapEntry>

      </identityProvidersPerSites>

      <!--Definitions of providers-->
      <identityProviders hint="list:AddIdentityProvider">
        <!--Auth0 provider-->
        <identityProvider id="ids3" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
          <param desc="name">$(id)</param>
          <param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
          <!--This text will be showed for button-->
          <caption></caption>
          <icon></icon>
          <!--Domain name which will be added when create a user-->
          <domain>sitecore</domain>
          <!--list of identity transfromations which are applied to the provider when a user signin-->
          <transformations hint="list:AddTransformation">
            <!--SetIdpClaim transformation-->
            <transformation name="set idp claim" ref="federatedAuthentication/sharedTransformations/setIdpClaim" />
          </transformations>
        </identityProvider>
      </identityProviders>
      <sharedTransformations hint="list:AddTransformation">
      </sharedTransformations>
    </federatedAuthentication>
  </sitecore>
</configuration>

请注意,我能够做到这一点的唯一方法是在验证时创建一个VirtualUser。考虑到几乎完全缺乏关于这个主题的文档,我不确定这是否是必要的步骤,或者我设置这个主题的方式是否有问题。

现在,VirtualUser就像冠军一样工作,我们很可能会保持这样的状态。但是,我想知道,这里是否需要创建一个VirtualUser,还是我做错了什么?

谢谢你的意见。

EN

回答 1

Stack Overflow用户

发布于 2017-11-28 14:02:44

我在您的总体配置中看到了几个问题,但最重要的是第一个问题(当然,解决方法必须删除):

  1. IdentityProvidersProcessor的实现必须包含只有--一种将身份验证配置为外部提供者的中间件,如UseOpenIdConnectAuthenticationUseAuth0AuthenticationUseFacebookAuthentication. --它不能配置cookie身份验证,因为它已经在Sitecore.Owin.Authentication.config . .中为您完成了 注意:如果您需要处理任何OWIN身份验证事件,只需使用相应的管道owin.cookieAuthentication.*操作:
代码语言:javascript
运行
复制
1. Remove your `UseCookieAuthentication` middleware.
2. Use  `string authenticationType = this.GetAuthenticationType();` to set the `SignInAsAuthenticationType` property of the `OpenIdConnectAuthenticationOptions` object (the `authenticationType` variable is unused in your code).

  1. 没有问题,但Sitecore.Owin.Authentication.Extensions命名空间中存在一个扩展方法,可以替换整个foreach语句: ( notification.AuthenticationTicket.Identity.ApplyClaimsTransformations(new TransformationContext(this.FederatedAuthenticationConfiguration,identityProvider);
  2. 您试图手动构建虚拟用户并对他们进行身份验证,但是Sitecore在修复第一个问题时会处理它。 操作:SecurityTokenValidated处理程序替换为: SecurityTokenValidated =Notification=>{ notification.AuthenticationTicket.Identity .ApplyClaimsTransformations(新的notification.AuthenticationTicket.Identity identityProvider);返回Task.CompletedTask;}
  3. 另一个“不是问题,但.”:这是非RTM 9.0构建的情况,但现在您不需要为每个身份提供程序手动指定setIdpClaim转换。在联邦身份验证/共享转换节点中指定的所有转换都会自动为所有身份提供程序执行。 操作:删除额外的转换
  4. 确保在RedirectUri属性中有一个适当的值。它必须在适当的RedirectUris对象的IdentityServer3.Core.Models.Client属性中表示。

完成所有操作后,您的外部用户将通过身份验证,但它还没有任何指定的角色。当其中任何一个都为真时,用户已经分配了角色:

  1. 用户存在于DB中,并在其中指定了角色。
  2. 用户的ClaimsIdentity对象具有"http://schemas.microsoft.com/ws/2008/06/identity/claims/role“类型的声明。

分配角色声明的最佳方法是使用索赔转换。

示例:假设您希望为包含在组中的所有Azure AD用户分配一个sitecore\Developer角色,对象id为3e12be6e-58af-479a-a4dc-7a3d5ef61c71。AzureAD身份提供程序的声明转换如下所示:

代码语言:javascript
运行
复制
    <transformation name="developer role" type="Sitecore.Owin.Authentication.Services.DefaultTransformation,Sitecore.Owin.Authentication">
        <sources hint="raw:AddSource">
            <claim name="groups" value="3e12be6e-58af-479a-a4dc-7a3d5ef61c70" />
        </sources>
        <targets hint="raw:AddTarget">
            <claim name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" value="sitecore\Developer " />
         </targets>
    </transformation>

重要注意事项:默认情况下, AzureAD不会将组索赔发回。您需要将groupMembershipClaims的值设置为应用程序清单中的SecurityGroup

现在您的用户有了角色,但是它的配置文件没有被填满。与声明转换不同,属性映射配置在所有标识提供程序之间共享。这背后的一般想法是为不同的身份提供者应用个性化的索赔转换,并接收您希望看到的带有索赔类型的“规范化”ClaimsIdentity。

例如,第一个提供者给你“第二个名字”索赔,第二个给你“姓”,第三个给你"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname“。然后,为相应的提供者编写两个声明转换,将“第二个名称”映射为“姓氏”,将"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname“映射到”姓氏“:

在第一个提供程序配置节点中:

代码语言:javascript
运行
复制
    <transformation name="surname" type="Sitecore.Owin.Authentication.Services.DefaultTransformation,Sitecore.Owin.Authentication">
        <sources hint="raw:AddSource">
            <claim name="second name" />
        </sources>
        <targets hint="raw:AddTarget">
            <claim name="surname" />
        </targets>
    </transformation>

在第二个提供程序配置节点中:

代码语言:javascript
运行
复制
    <transformation name="surname" type="Sitecore.Owin.Authentication.Services.DefaultTransformation,Sitecore.Owin.Authentication">
        <sources hint="raw:AddSource">
            <claim name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" />
        </sources>
        <targets hint="raw:AddTarget">
            <claim name="surname" />
        </targets>
    </transformation>

从现在开始,您有一个规范化的ClaimsIdentity,您可以编写一个属性映射:

代码语言:javascript
运行
复制
    <map name="surname" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication" resolve="true">
      <data hint="raw:AddData">
        <source name="surname" />
        <target name="Surname" />
      </data>
    </map>

用户配置文件数据可以用user.Profile["Surname"]读取。

注意:如果需要的话,实现自定义声明转换和属性映射是可能的,也是很容易的。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47405473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档