1

背景

我对 Umbraco 很陌生,但一直在尝试将IdentityServer4用于 Umbraco 的 BackOffice。对于 IDP,我使用了此处的内存配置(is4inmem 模板) 。

对于 Umbraco,我使用UmbracoIdentityExtensions来配置 OpenId Connect。

我一直主要关注教程(但是,这是针对 Umbraco 7)。

问题

我确实有我配置的“使用 OpenId 连接登录”按钮,但是当我尝试使用 IDP 登录时,Umbraco 没有让我登录。我不断返回登录页面。但是,每当我进入 IDP 页面时,我都会登录并可以看到我已授予访问权限,如下图所示。 在此处输入图像描述

每当我使用 Umbraco 帐户登录,然后尝试“链接您的 OpenId Connect 帐户”时,它什么也不做,但在注销时屏幕上会出现一条错误消息:“发生错误,无法获取外部登录信息”我尝试使用不同的配置设置,但没有成功。

代码

IDP 配置文件

public static IEnumerable<IdentityResource> Ids =>
            new IdentityResource[]
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email(),
                new IdentityResource(
                    name: "application.profile",
                    displayName: "Application profile",
                    claimTypes: new[] { ClaimTypes.GivenName, ClaimTypes.Surname }
                )
            };

... etc ...

 public static IEnumerable<Client> Clients =>
            new Client[]
            {
                new Client
                {
                    ClientId = "u-client-bo",
                    ClientSecrets = new List<Secret>
                    {
                        new Secret("secret".Sha256()),
                    },
                    ClientName = "Umbraco Client",
                    AllowedGrantTypes = GrantTypes.Hybrid,
                    RequireConsent = false,
                    RedirectUris           = { "https://localhost:44302/Umbraco" },
                    PostLogoutRedirectUris = { "https://localhost:44302/Umbraco" },
                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Email,
                        "application.profile",
                    },
                    AllowAccessTokensViaBrowser = true,
                    AlwaysIncludeUserClaimsInIdToken = false
                }
            };

对于 Umbraco,我已将UmbracoCustomOwinStartup编辑为以下内容:

public class UmbracoCustomOwinStartup : UmbracoDefaultOwinStartup
{
    protected override void ConfigureUmbracoUserManager(IAppBuilder app)
    {
        app.ConfigureUserManagerForUmbracoBackOffice(
            Services,
            Mapper,
            UmbracoSettings.Content,
            GlobalSettings,

            global::Umbraco.Core.Security.MembershipProviderExtensions.GetUsersMembershipProvider().AsUmbracoMembershipProvider());
    }

    protected override void ConfigureUmbracoAuthentication(IAppBuilder app)
    {
        app
            .UseUmbracoBackOfficeCookieAuthentication(UmbracoContextAccessor, RuntimeState, Services.UserService, GlobalSettings, UmbracoSettings.Security, PipelineStage.Authenticate)
            .UseUmbracoBackOfficeExternalCookieAuthentication(UmbracoContextAccessor, RuntimeState, GlobalSettings, PipelineStage.Authenticate)
            .UseUmbracoPreviewAuthentication(UmbracoContextAccessor, RuntimeState, GlobalSettings, UmbracoSettings.Security, PipelineStage.Authorize);

        var identityOptions = new OpenIdConnectAuthenticationOptions
        {
            ClientId = "u-client-bo",
            SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
            Authority = "https://localhost:44393",
            RedirectUri = "https://localhost:44302/Umbraco",
            ResponseType = "code id_token token",
            Scope = "openid profile application.profile",
            PostLogoutRedirectUri = "https://localhost:44302/Umbraco",

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = ClaimsTransformer.GenerateUserIdentityAsync
            }
        };

        // Configure BackOffice Account Link button and style
        identityOptions.ForUmbracoBackOffice("btn-microsoft", "fa-windows");
        identityOptions.Caption = "OpenId Connect";

        // Configure AutoLinking
        identityOptions.SetExternalSignInAutoLinkOptions(
            new ExternalSignInAutoLinkOptions(autoLinkExternalAccount: true));

        app.UseOpenIdConnectAuthentication(identityOptions);
    }
}

ClaimsTransformer.GenerateUserIdentityAsync方法将其他声明添加到身份。

我是否缺少其他配置或组件?

提前致谢!

4

1 回答 1

5

我终于想通了。有几个问题:

1.更正auth cookie

而不是使用DefaultAuthenticationTypes.ExternalCookieas SignInAsAuthenticationType,我现在使用Umbraco.Core.Constants.Security.BackOfficeExternalAuthenticationType.

2.设置AuthenticationType

设置AuthenticationTypeOpenIdConnectAuthenticationOptions. 它必须与名称匹配Authority才能使自动链接起作用。

重要:在显式之后再次设置它,identityOptions.ForUmbracoBackOffice("btn-microsoft", "fa-windows");因为它'Umbraco.'在方法调用之后为其添加前缀。

3. 包括电子邮件声明

我已经添加了电子邮件声明,这也是自动链接工作所必需的。

Scope = "openid email profile application.profile",

4. 确保您有任何形式的名称声明

我已在 IDP 中设置AlwaysIncludeUserClaimsInIdTokentrue因此 ID 声明会自动在 Umbraco 中获取。我ClaimsTransformer现在的样子是这样的:

public class ClaimsTransformer
{
    public static async Task GenerateUserIdentityAsync(
        SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
    {
        // Now this contains ID claims (e.g. GivenName in my case)
        var id = notification.AuthenticationTicket.Identity;

        var identityUser = new ClaimsIdentity(
            id.Claims, // copy the claims I have
            notification.AuthenticationTicket.Identity.AuthenticationType,
            // set the nameType, so Umbraco can use the 'ExternalLogin.Name' for auto-link to work
            ClaimTypes.GivenName, // <-- You have to set a correct nameType claim
            ClaimTypes.Role);

         notification.AuthenticationTicket = new AuthenticationTicket(identityUser,
                notification.AuthenticationTicket.Properties);
    }
}

5. 移除其他 Umbraco Auth 中间件

app.UseUmbracoBackOfficeXXX在我的情况下不需要这些语句,事实上,它们破坏了功能。我UmbracoCustomOwinStartup现在的样子是这样的:

public class UmbracoCustomOwinStartup : UmbracoDefaultOwinStartup
{
    protected override void ConfigureUmbracoAuthentication(IAppBuilder app)
    {
        base.ConfigureUmbracoAuthentication(app);

        var identityOptions = new OpenIdConnectAuthenticationOptions
        {
            ClientId = "u-client-bo",
            SignInAsAuthenticationType = Umbraco.Core.Constants.Security.BackOfficeExternalAuthenticationType,
            AuthenticationType = "https://localhost:44393",
            Authority = "https://localhost:44393",
            RedirectUri = "https://localhost:44302/Umbraco",
            ResponseType = "code id_token token",
            Scope = "openid email profile application.profile",
            PostLogoutRedirectUri = "https://localhost:44302/Umbraco",

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = ClaimsTransformer.GenerateUserIdentityAsync
            }
        };

        // Configure BackOffice Account Link button and style
        identityOptions.ForUmbracoBackOffice("btn-microsoft", "fa-windows");
        identityOptions.Caption = "OpenId Connect";

        identityOptions.AuthenticationType = "https://localhost:44393";

        // Configure AutoLinking
        identityOptions.SetExternalSignInAutoLinkOptions(
            new ExternalSignInAutoLinkOptions(autoLinkExternalAccount: true));

        app.UseOpenIdConnectAuthentication(identityOptions);
    }

}

提示:不要忘记在您的web.config.

我希望你们中的一些人觉得这很有帮助,我找不到很多关于 Umbraco 8 和 IdentityServer4 的文档。

于 2020-03-09T17:53:18.177 回答