Sitecore 配置 Oauth2.0 OpenId Connect

写好参数通过Config 配置到 sitecore pipeline 即可

public class OpenIdIdentityProvider : IdentityProvidersProcessor
    {
        protected override string IdentityProviderName => OpenIdModel.IdentityProvider;

        public OpenIdIdentityProvider(FederatedAuthenticationConfiguration federatedAuthenticationConfiguration, ICookieManager cookieManager, BaseSettings settings) : base(federatedAuthenticationConfiguration, cookieManager, settings)
        {
        }

        protected override void ProcessCore(IdentityProvidersArgs args)
        {
            Assert.ArgumentNotNull(args, nameof(args));
            try
            {
                IdentityProvider identityProvider = GetIdentityProvider();
                string authenticationType = GetAuthenticationType();
                string prefix = Settings.GetSetting(OpenIdModel.OpenIdPrefix);
                string clientId = Settings.GetSetting(OpenIdModel.ClientId);
                string authority = $"{Sitecore.StringUtil.EnsurePostfix('/', prefix)}{Settings.GetSetting(OpenIdModel.AuthorizeEndpoint)}";
                string metaAddress = Settings.GetSetting(OpenIdModel.MetaAddress);
                string redirectUri = Settings.GetSetting(OpenIdModel.RedirectURI);
                string logout = Settings.GetSetting(OpenIdModel.PostLogoutRedirectURI);
                var options = new OpenIdConnectAuthenticationOptions(authenticationType)
                {
                    Caption = identityProvider.Caption,
                    AuthenticationType = authenticationType,
                    AuthenticationMode = AuthenticationMode.Passive,
                    ResponseType = OpenIdConnectResponseType.Code,
                    ClientId = clientId,
                    CookieManager = CookieManager,
                    MetadataAddress = metaAddress,
                    RedirectUri = redirectUri,
                    Authority = authority,
                    UseTokenLifetime = true,
                    RedeemCode = true,
                    SaveTokens = true,
                    Scope = $"{OpenIdConnectScope.OpenIdProfile} {clientId}",
                    ResponseMode = OpenIdConnectResponseMode.Query,
                    PostLogoutRedirectUri = logout,
                    TokenValidationParameters = new TokenValidationParameters() { NameClaimType = "name" },
                    Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        RedirectToIdentityProvider = context =>
                        {
                            if (context.ProtocolMessage.RequestType.Equals(OpenIdConnectRequestType.Authentication))
                            {
                                string codeVerifier = CryptoRandom.CreateUniqueId(32);
                                string codeChallenge;
                                using (SHA256 sha256 = SHA256.Create())
                                {
                                    byte[] challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
                                    codeChallenge = Base64Url.Encode(challengeBytes);
                                }

                                context.ProtocolMessage.Parameters.Add("code_challenge", codeChallenge);
                                context.ProtocolMessage.Parameters.Add("code_challenge_method", "S256");
                                RememberCodeVerifier(context, codeVerifier);
                            }
                            return Task.CompletedTask;
                        },
                        AuthorizationCodeReceived = context =>
                        {
                        	// 验证通过,收到code 和state,触发这里的logic, 这里写上,自动呼叫获取id_token 的logic
                            Helper.Logger.Info($"AuthorizationCodeReceived");
                            string codeVerifier = RetrieveCodeVerifier(context);
                            context.TokenEndpointRequest.SetParameter("code_verifier", codeVerifier);
                            //context.AuthenticationTicket.Identity.ApplyClaimsTransformations(new TransformationContext(FederatedAuthenticationConfiguration, identityProvider));
                            return Task.CompletedTask;

                        },
                        SecurityTokenValidated = context =>
                        {
                        	//收到最终我们需要的id_token时,触发这里
                            Helper.Logger.Info($"SecurityTokenValidated");
                            context.AuthenticationTicket.Identity.ApplyClaimsTransformations(new TransformationContext(FederatedAuthenticationConfiguration, identityProvider));
                            return Task.CompletedTask;
                        },
                        AuthenticationFailed = context =>
                        {
                            Helper.Logger.Info($"AuthenticationFailed");
                            context.HandleResponse();
                            Helper.Logger.Error(context.Exception.ToString(), context.Exception);
                            context.Response.Redirect(logout);
                            return Task.FromResult(0);
                        },
                        SecurityTokenReceived = context =>
                        {
                            Helper.Logger.Info($"SecurityTokenReceived");
                            return Task.CompletedTask;
                        },                        
                    }
                };

                args.App.UseOpenIdConnectAuthentication(options);
            }
            catch (Exception ex)
            {
                Helper.Logger.Error(ex.ToString(), ex);
            }
        }

        private void RememberCodeVerifier(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context, string codeVerifier)
        {
            var properties = new AuthenticationProperties();
            properties.Dictionary.Add("cv", codeVerifier);
            context.Options.CookieManager.AppendResponseCookie(
                context.OwinContext,
                GetCodeVerifierKey(context.ProtocolMessage.State),
                Convert.ToBase64String(Encoding.UTF8.GetBytes(context.Options.StateDataFormat.Protect(properties))),
                new CookieOptions
                {
                    HttpOnly = true,
                    Secure = context.Request.IsSecure,
                    Expires = DateTime.UtcNow + context.Options.ProtocolValidator.NonceLifetime
                });
        }

        private string RetrieveCodeVerifier(AuthorizationCodeReceivedNotification context)
        {
            string key = GetCodeVerifierKey(context.ProtocolMessage.State);

            string codeVerifierCookie = context.Options.CookieManager.GetRequestCookie(context.OwinContext, key);
            if (codeVerifierCookie != null)
            {
                CookieOptions cookieOptions = new CookieOptions
                {
                    HttpOnly = true,
                    Secure = context.Request.IsSecure
                };
                context.Options.CookieManager.DeleteCookie(context.OwinContext, key, cookieOptions);
            }

            AuthenticationProperties cookieProperties = context.Options.StateDataFormat.Unprotect(Encoding.UTF8.GetString(Convert.FromBase64String(codeVerifierCookie)));
            cookieProperties.Dictionary.TryGetValue("cv", out var codeVerifier);

            return codeVerifier;
        }

        private string GetCodeVerifierKey(string state)
        {
            using (var hash = SHA256.Create())
                return $"{OpenIdConnectAuthenticationDefaults.CookiePrefix}cv.{Convert.ToBase64String(hash.ComputeHash(Encoding.UTF8.GetBytes(state)))}";
        }
    }

config 如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:environment="http://www.sitecore.net/xmlconfig/environment/">
	<sitecore>
    <sc.variable name="OpenIdTenant" value="xxxx" /> <!-- your data -->
    <sc.variable name="OpenIdSignInUpPage" value="xxxx" /> <!-- your data -->
		<settings>
      <setting name="OpenIdPrefix" value="$(OpenIdTenant)/$(OpenIdSignInUpPage)/oauth2/v2.0" />
      <setting name="ClientId" value="xxxx" /> <!-- your data -->
      <setting name="MetaAddress" value="$(OpenIdTenant)/$(OpenIdSignInUpPage)/v2.0/.well-known/openid-configuration" />
      <setting name="AuthorizeEndpoint" value="authorize" />
      <setting name="TokenEndpoint" value="token" />
      <setting name="LogoutEndpoint" value="logout" />
      <setting name="PostLogoutRedirectURI" value="xxxx" /> <!-- your data -->
      <setting name="RedirectURI" value="xxxxx" /> <!-- your data -->
		</settings>
		<pipelines>
			<owin.identityProviders>
				<processor type="namespance.className, dll Name" resolve="true" />
			</owin.identityProviders>
		</pipelines>

		<federatedAuthentication>
			<identityProviders hint="list:AddIdentityProvider">
				<identityProvider id="OpenId" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
					<param desc="name">$(id)</param>
					<param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
					<caption>Sign-in with Open Id</caption>
					<!-- Update your domain if not default -->
					<domain>extranet</domain>
					<icon>/sitecore/shell/themes/standard/Images/24x24/msazure.png</icon>
					<transformations hint="list:AddTransformation">
						<transformation name="idp" value="OpenId" type="Sitecore.Owin.Authentication.Services.SetIdpClaimTransform, Sitecore.Owin.Authentication" />
					</transformations>
				</identityProvider>
			</identityProviders>

			<propertyInitializer type="Sitecore.Owin.Authentication.Services.PropertyInitializer, Sitecore.Owin.Authentication">
				<maps hint="list" resolve="true">
					<map name="Email claim" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication" resolve="true">
						<data hint="raw:AddData">
							<source name="Email" />
							<target name="Email" />
						</data>
					</map>
					<map name="Display name claim" type="Sitecore.Owin.Authentication.Services.DefaultClaimToPropertyMapper, Sitecore.Owin.Authentication" resolve="true">
						<data hint="raw:AddData">
							<source name="name" />
							<target name="FullName" />
						</data>
					</map>
				</maps>
			</propertyInitializer>
			<identityProvidersPerSites>
				<mapEntry name="all" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication" resolve="true">
					<sites hint="list" resolve="true">
						<site>website</site>
					</sites>
					<identityProviders hint="list:AddIdentityProvider">
						<identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='OpenId']" />
					</identityProviders>
					<externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication" resolve="true">
						<IsPersistentUser>false</IsPersistentUser>
					</externalUserBuilder>
				</mapEntry>
			</identityProvidersPerSites>
		</federatedAuthentication>
	</sitecore>
</configuration>

呼叫 sign in or up 接口

[HttpPost]
        public ActionResult OnePass()
        {
            string idp = "xxx"; // 对应config的id
            BaseCorePipelineManager corePipelineManager = DependencyResolver.Current.GetService<BaseCorePipelineManager>();
            GetSignInUrlInfoArgs args = new GetSignInUrlInfoArgs(Sitecore.Context.Site.Name, "/"); //Settings.GetAppSetting("RedirectURI")
            GetSignInUrlInfoPipeline.Run(corePipelineManager, args);

            //Get link to IDP
            var redirectToIdp = args.Result.FirstOrDefault(z => z.IdentityProvider.Equals(idp, StringComparison.OrdinalIgnoreCase)).Href;
            PostRedirect(redirectToIdp);
            return null;
        }
        private void PostRedirect(string url)
        {
            //For security, Login required form post method
            Response.Clear();
            var sb = new System.Text.StringBuilder();
            sb.Append("<html>");
            sb.AppendFormat("<body οnlοad='document.forms[0].submit()'>");
            sb.AppendFormat("<form action='{0}' method='post'>", url);
            sb.Append("</form>");
            sb.Append("</body>");
            sb.Append("</html>");
            Response.Write(sb.ToString());
            Response.End();
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值