【问题标题】:Azure AD B2C API Access through Postman and Web app通过 Postman 和 Web 应用访问 Azure AD B2C API
【发布时间】:2023-01-19 22:32:57
【问题描述】:

作为我关于如何设置 ROPC Flow 的问题的后续行动。我想通过 ROPC 流(目前使用默认用户流)以及我的 Web 应用程序访问我的 API,该应用程序在登录时使用自定义策略。这会产生两个不同的访问令牌。左侧是使用 AcquireTokenSilent 调用接收到的访问令牌,右侧是使用 ROPC 通过邮递员接收到的访问令牌。 自定义策略令牌(左侧)显示“已拒绝此请求的授权”。错误,而右边的令牌很好。我假设自定义策略令牌不起作用,因为它不包含 tfp 声明(如果包含,那将是一个不同的声明)。

我如何设置才能在使用自定义策略的同时仍然使用 ROPC 流程?我想让自定义策略中的当前用户旅程保持不变。尽管如果有可能以某种方式将 ROPC 添加为它的选项,那就没问题了。

【问题讨论】:

    标签: azure azure-ad-b2c azure-ad-b2c-custom-policy


    【解决方案1】:

    根据上面的描述,您正在使用两种策略类型 - 用户流和自定义策略。而且,您正试图在两者之间获得 SSO。

    这不是受支持的方案。这是因为令牌使用不同的密钥来签署令牌。

    如果您的场景需要自定义策略,我建议使用此文档将用户流 ROPC 转换为自定义策略https://learn.microsoft.com/en-us/azure/active-directory-b2c/add-ropc-policy?tabs=app-reg-ga&pivots=b2c-custom-policy

    【讨论】:

    • 感谢您的回复,您是说如果我将 ROPC 用户流更改为自定义策略,那么我将能够使用这两种自定义策略向 API 发送请求?
    【解决方案2】:

    所以我终于找到了一种在 .NET Framework 中执行此操作的方法,如果你想要一个适用于 .NET Core 的解决方案,你将遗憾地不得不寻找其他地方。

    在您的启动中添加以下内容。

         /*
         * Configure the authorization OWIN middleware
         */
        private void ConfigureAuthenticationAzure(IAppBuilder app)
        {
            app.UseOAuthBearerAuthentication(CreateOptions(ClientId, SignUpSignInPolicy, azureDiscoveryEndpoint));
            app.UseOAuthBearerAuthentication(CreateOptions(ClientId, ApiPolicy, azureDiscoveryEndpointAPI));
        }
    
    
        private OAuthBearerAuthenticationOptions CreateOptions(string audience, string policy, string discoveryEndpoint)
        {
            var metadataEndpoint = String.Format(discoveryEndpoint, Tenant, policy);
    
            // This is the default check, in OnValidateIdentity, we check for more.
            TokenValidationParameters tvps = new TokenValidationParameters
            {
                // This is where you specify that your API only accepts tokens from its own clients
                ValidAudience = ClientId,
                ValidateAudience = true,
                AuthenticationType = policy,
                NameClaimType = "http://schemas.microsoft.com/identity/claims/objectidentifier",
                ValidateIssuer = true,
            };
    
    
            return new OAuthBearerAuthenticationOptions
            {
                AccessTokenFormat = new JwtFormat(tvps, new OpenIdConnectCachingSecurityTokenProvider(metadataEndpoint)),
    
                Provider = new OAuthBearerAuthenticationProvider
                {
                    OnValidateIdentity = async context =>
                    {
                        try
                        {
                            var authorizationHeader = context.Request.Headers.Get("Authorization");
                            var userJwtToken = authorizationHeader.Substring("Bearer ".Length).Trim();
    
    
                            var ticket = context.Ticket;
                            //var identity = ticket.Identity;
                            
    
                            var jwtSecurityToken = new JwtSecurityToken(userJwtToken);
                            var expiration = jwtSecurityToken.ValidTo.ToLocalTime();
                            if (expiration < DateTime.Now)
                            {
                                log.Warn("The JWT token has expired.");
                                context.Rejected();
                                return;
                            }
                            ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(discoveryEndpoint, new OpenIdConnectConfigurationRetriever());
                            OpenIdConnectConfiguration openIdconfig = configManager.GetConfigurationAsync().Result;
                            var validationParameters = new TokenValidationParameters
                            {
                                ValidateIssuerSigningKey = true,
                                IssuerSigningKeys = openIdconfig.SigningKeys,
                                ValidateIssuer = true,
                                ValidIssuer = $"{AzureIssuer.ToLower()}/v2.0/",
                                ValidateAudience = true,
                                ValidAudience = audience,
                                ValidateLifetime = true,
                                //ClockSkew = TimeSpan.Zero
                            };
    
                            var handler = new JwtSecurityTokenHandler();
                            SecurityToken securityToken;
                            var principal = handler.ValidateToken(userJwtToken, validationParameters, out securityToken);
    
                            var policyName = principal.FindFirst("tfp")?.Value;
    
                            // Add the name claim type for this authentication type
                            if (policyName.ToLower() == DefaultPolicy.ToLower()) // Sign In Only policy...
                            {
                                // Run specific code here for the policy that just sent a token back to the application...
                                context.Validated(ticket);
                                return;
                            }
                            else if (policyName.ToLower() == SignUpSignInPolicy.ToLower())
                            {
                                context.Validated(ticket);
                                return;
                            }
                            
                            context.Rejected();
                            return;
    
                        }
                        catch(Exception ex)
                        {
                            context.Rejected();
                            return;
                        }
                    }
                }
            };
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-26
      • 1970-01-01
      • 2018-04-26
      • 2021-10-26
      • 2018-03-09
      • 1970-01-01
      • 1970-01-01
      • 2021-02-22
      相关资源
      最近更新 更多