Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Azure B2C-使用msal获得调用图API的授权_Azure_Microsoft Graph Api_Azure Ad B2c - Fatal编程技术网

Azure B2C-使用msal获得调用图API的授权

Azure B2C-使用msal获得调用图API的授权,azure,microsoft-graph-api,azure-ad-b2c,Azure,Microsoft Graph Api,Azure Ad B2c,我最近开始与B2C合作。我设法让他们使用MSAL和API与我自己的租户一起工作 现在我想: 了解如何在不使用API的情况下运行此示例。该示例使用作用域获取对API的读/写访问权。如果我从应用程序中删除对API的引用,它将不再工作。当然,应该有某种方法可以在不需要API的情况下对B2C进行身份验证?这对我的应用程序来说并不重要,但我最想知道的是,作为身份验证过程的一部分,Web服务是否必须存在 与Graph Api(Windows或Microsoft Graph?)通信。MS提供了ADAL和一些控

我最近开始与B2C合作。我设法让他们使用MSAL和API与我自己的租户一起工作

现在我想:

  • 了解如何在不使用API的情况下运行此示例。该示例使用作用域获取对API的读/写访问权。如果我从应用程序中删除对API的引用,它将不再工作。当然,应该有某种方法可以在不需要API的情况下对B2C进行身份验证?这对我的应用程序来说并不重要,但我最想知道的是,作为身份验证过程的一部分,Web服务是否必须存在
  • 与Graph Api(Windows或Microsoft Graph?)通信。MS提供了ADAL和一些控制台应用程序。我找不到使用MSAL的示例,因此在将其合并到我自己的应用程序中时遇到问题。现在可以使用MSAL调用图形API了吗?如果是,是否有一些文档说明如何在某处执行此操作 我试着简单地按照上面的文档注册一个应用程序/授予它权限。然后将客户机ID/密钥放入我自己的应用程序(第一个示例中的MSAL应用程序),但随后我从B2C收到一条消息,如下所示:

    public partial class Startup
    {
    
        // App config settings
        public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
        public static string ClientSecret = ConfigurationManager.AppSettings["ida:ClientSecret"];
        public static string AadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
        public static string Tenant = ConfigurationManager.AppSettings["ida:Tenant"];
        public static string RedirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];
        public static string ServiceUrl = ConfigurationManager.AppSettings["api:TaskServiceUrl"];
    
        public static string ApiIdentifier = ConfigurationManager.AppSettings["api:ApiIdentifier"];
        public static string ReadTasksScope = ApiIdentifier + ConfigurationManager.AppSettings["api:ReadScope"];
        public static string WriteTasksScope = ApiIdentifier + ConfigurationManager.AppSettings["api:WriteScope"];
        public static string[] Scopes = new string[] { ReadTasksScope, WriteTasksScope };
    
        // B2C policy identifiers
        public static string SignUpSignInPolicyId = ConfigurationManager.AppSettings["ida:SignUpSignInPolicyId"];
        public static string EditProfilePolicyId = ConfigurationManager.AppSettings["ida:EditProfilePolicyId"];
        public static string ResetPasswordPolicyId = ConfigurationManager.AppSettings["ida:ResetPasswordPolicyId"];
    
        public static string DefaultPolicy = SignUpSignInPolicyId;
    
        // OWIN auth middleware constants
        public const string ObjectIdElement = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";
    
        // Authorities
        public static string Authority = String.Format(AadInstance, Tenant, DefaultPolicy);
    
        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                // Generate the metadata address using the tenant and policy information
                MetadataAddress = String.Format(AadInstance, Tenant, DefaultPolicy),
    
                // These are standard OpenID Connect parameters, with values pulled from web.config
                ClientId = ClientId,
                    RedirectUri = RedirectUri,
                    PostLogoutRedirectUri = RedirectUri,
    
                // Specify the callbacks for each type of notifications
                Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        RedirectToIdentityProvider = OnRedirectToIdentityProvider,
                        AuthorizationCodeReceived = OnAuthorizationCodeReceived,
                        AuthenticationFailed = OnAuthenticationFailed,
                    },
    
                // Specify the claims to validate
                TokenValidationParameters = new TokenValidationParameters
                    {
                        NameClaimType = "name"
                    },
    
                // Specify the scope by appending all of the scopes requested into one string (seperated by a blank space)
                Scope = $"{OpenIdConnectScopes.OpenId} {ReadTasksScope} {WriteTasksScope}"
                }
            );
    
        }
    
        /*
         *  On each call to Azure AD B2C, check if a policy (e.g. the profile edit or password reset policy) has been specified in the OWIN context.
         *  If so, use that policy when making the call. Also, don't request a code (since it won't be needed).
         */
        private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
        {
            var policy = notification.OwinContext.Get<string>("Policy");
    
            if (!string.IsNullOrEmpty(policy) && !policy.Equals(DefaultPolicy))
            {
                notification.ProtocolMessage.Scope = OpenIdConnectScopes.OpenId;
                notification.ProtocolMessage.ResponseType = OpenIdConnectResponseTypes.IdToken;
                notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(DefaultPolicy.ToLower(), policy.ToLower());
            }
    
            return Task.FromResult(0);
        }
    
        /*
         * Catch any failures received by the authentication middleware and handle appropriately
         */
        private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
        {
            notification.HandleResponse();
    
            // Handle the error code that Azure AD B2C throws when trying to reset a password from the login page 
            // because password reset is not supported by a "sign-up or sign-in policy"
            if (notification.ProtocolMessage.ErrorDescription != null && notification.ProtocolMessage.ErrorDescription.Contains("AADB2C90118"))
            {
                // If the user clicked the reset password link, redirect to the reset password route
                notification.Response.Redirect("/Account/ResetPassword");
            }
            else if (notification.Exception.Message == "access_denied")
            {
                notification.Response.Redirect("/");
            }
            else
            {
                notification.Response.Redirect("/Home/Error?message=" + notification.Exception.Message);
            }
    
            return Task.FromResult(0);
        }
    
    
        /*
         * Callback function when an authorization code is received 
         */
        private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification)
        {
            // Extract the code from the response notification
            var code = notification.Code;
    
            string signedInUserID = notification.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache = new MSALSessionCache(signedInUserID, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, new ClientCredential(ClientSecret), userTokenCache, null);
            try
            {
                AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, Scopes);
            }
            catch (Exception ex)
            {
                //TODO: Handle
                throw;
            }
        }
    
    相关ID:01040e7b-846c-4f81-9a0f-ff515fd00398 时间戳:2018-01-30 10:55:37Z AADB2C90068:提供的ID为“9cd938c6-d3ed-4146-aee5-a661cd7d984b”的应用程序对此服务无效。请使用通过B2C门户创建的应用程序,然后重试

    的确,它没有通过B2C门户网站注册,但这是说明中所说的;在应用程序注册下的B2C租户中注册,而不是B2C门户

    所有魔术发生的Startup类如下所示:

    public partial class Startup
    {
    
        // App config settings
        public static string ClientId = ConfigurationManager.AppSettings["ida:ClientId"];
        public static string ClientSecret = ConfigurationManager.AppSettings["ida:ClientSecret"];
        public static string AadInstance = ConfigurationManager.AppSettings["ida:AadInstance"];
        public static string Tenant = ConfigurationManager.AppSettings["ida:Tenant"];
        public static string RedirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];
        public static string ServiceUrl = ConfigurationManager.AppSettings["api:TaskServiceUrl"];
    
        public static string ApiIdentifier = ConfigurationManager.AppSettings["api:ApiIdentifier"];
        public static string ReadTasksScope = ApiIdentifier + ConfigurationManager.AppSettings["api:ReadScope"];
        public static string WriteTasksScope = ApiIdentifier + ConfigurationManager.AppSettings["api:WriteScope"];
        public static string[] Scopes = new string[] { ReadTasksScope, WriteTasksScope };
    
        // B2C policy identifiers
        public static string SignUpSignInPolicyId = ConfigurationManager.AppSettings["ida:SignUpSignInPolicyId"];
        public static string EditProfilePolicyId = ConfigurationManager.AppSettings["ida:EditProfilePolicyId"];
        public static string ResetPasswordPolicyId = ConfigurationManager.AppSettings["ida:ResetPasswordPolicyId"];
    
        public static string DefaultPolicy = SignUpSignInPolicyId;
    
        // OWIN auth middleware constants
        public const string ObjectIdElement = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";
    
        // Authorities
        public static string Authority = String.Format(AadInstance, Tenant, DefaultPolicy);
    
        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                // Generate the metadata address using the tenant and policy information
                MetadataAddress = String.Format(AadInstance, Tenant, DefaultPolicy),
    
                // These are standard OpenID Connect parameters, with values pulled from web.config
                ClientId = ClientId,
                    RedirectUri = RedirectUri,
                    PostLogoutRedirectUri = RedirectUri,
    
                // Specify the callbacks for each type of notifications
                Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        RedirectToIdentityProvider = OnRedirectToIdentityProvider,
                        AuthorizationCodeReceived = OnAuthorizationCodeReceived,
                        AuthenticationFailed = OnAuthenticationFailed,
                    },
    
                // Specify the claims to validate
                TokenValidationParameters = new TokenValidationParameters
                    {
                        NameClaimType = "name"
                    },
    
                // Specify the scope by appending all of the scopes requested into one string (seperated by a blank space)
                Scope = $"{OpenIdConnectScopes.OpenId} {ReadTasksScope} {WriteTasksScope}"
                }
            );
    
        }
    
        /*
         *  On each call to Azure AD B2C, check if a policy (e.g. the profile edit or password reset policy) has been specified in the OWIN context.
         *  If so, use that policy when making the call. Also, don't request a code (since it won't be needed).
         */
        private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
        {
            var policy = notification.OwinContext.Get<string>("Policy");
    
            if (!string.IsNullOrEmpty(policy) && !policy.Equals(DefaultPolicy))
            {
                notification.ProtocolMessage.Scope = OpenIdConnectScopes.OpenId;
                notification.ProtocolMessage.ResponseType = OpenIdConnectResponseTypes.IdToken;
                notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(DefaultPolicy.ToLower(), policy.ToLower());
            }
    
            return Task.FromResult(0);
        }
    
        /*
         * Catch any failures received by the authentication middleware and handle appropriately
         */
        private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
        {
            notification.HandleResponse();
    
            // Handle the error code that Azure AD B2C throws when trying to reset a password from the login page 
            // because password reset is not supported by a "sign-up or sign-in policy"
            if (notification.ProtocolMessage.ErrorDescription != null && notification.ProtocolMessage.ErrorDescription.Contains("AADB2C90118"))
            {
                // If the user clicked the reset password link, redirect to the reset password route
                notification.Response.Redirect("/Account/ResetPassword");
            }
            else if (notification.Exception.Message == "access_denied")
            {
                notification.Response.Redirect("/");
            }
            else
            {
                notification.Response.Redirect("/Home/Error?message=" + notification.Exception.Message);
            }
    
            return Task.FromResult(0);
        }
    
    
        /*
         * Callback function when an authorization code is received 
         */
        private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification)
        {
            // Extract the code from the response notification
            var code = notification.Code;
    
            string signedInUserID = notification.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache = new MSALSessionCache(signedInUserID, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, new ClientCredential(ClientSecret), userTokenCache, null);
            try
            {
                AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, Scopes);
            }
            catch (Exception ex)
            {
                //TODO: Handle
                throw;
            }
        }
    
    公共部分类启动
    {
    //应用程序配置设置
    公共静态字符串ClientId=ConfigurationManager.AppSettings[“ida:ClientId”];
    公共静态字符串ClientSecret=ConfigurationManager.AppSettings[“ida:ClientSecret”];
    公共静态字符串AadInstance=ConfigurationManager.AppSettings[“ida:AadInstance”];
    公共静态字符串Tenant=ConfigurationManager.AppSettings[“ida:Tenant”];
    公共静态字符串RedirectUri=ConfigurationManager.AppSettings[“ida:RedirectUri”];
    公共静态字符串ServiceUrl=ConfigurationManager.AppSettings[“api:TaskServiceUrl”];
    公共静态字符串ApiIdentifier=ConfigurationManager.AppSettings[“api:ApiIdentifier”];
    公共静态字符串readtaskscope=apidentifier+ConfigurationManager.AppSettings[“api:ReadScope”];
    公共静态字符串WriteTaskScope=APIDENTIFIER+ConfigurationManager.AppSettings[“api:WriteScope”];
    公共静态字符串[]范围=新字符串[]{ReadTasksScope,WriteTasksScope};
    //B2C策略标识符
    公共静态字符串signupsignnpolicyid=ConfigurationManager.AppSettings[“ida:signupsignnpolicyid”];
    公共静态字符串EditProfilePolicyId=ConfigurationManager.AppSettings[“ida:EditProfilePolicyId”];
    公共静态字符串ResetPasswordPolicyId=ConfigurationManager.AppSettings[“ida:ResetPasswordPolicyId”];
    公共静态字符串DefaultPolicy=signupsignnpolicyid;
    //OWIN身份验证中间件常量
    public const字符串objectdelement=”http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";
    //当局
    publicstaticstringauthority=string.Format(AadInstance、Tenant、DefaultPolicy);
    public void ConfigureAuth(IAppBuilder应用程序)
    {
    app.UseCookieAuthentication(新的CookieAuthenticationOptions());
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseOpenIdConnectAuthentication(
    新的OpenIdConnectAuthenticationOptions
    {
    //使用租户和策略信息生成元数据地址
    MetadataAddress=String.Format(AadInstance、租户、DefaultPolicy),
    //这些是标准的OpenID连接参数,其值来自web.config
    ClientId=ClientId,
    RedirectUri=RedirectUri,
    PostLogoutRedirectUri=RedirectUri,
    //为每种类型的通知指定回调
    通知=新的OpenIdConnectAuthenticationNotifications
    {
    RedirectToIdentityProvider=OnRedirectToIdentityProvider,
    AuthorizationCodeReceived=OnAuthorizationCodeReceived,
    AuthenticationFailed=OnAuthenticationFailed,
    },
    //指定要验证的声明
    TokenValidationParameters=新的TokenValidationParameters
    {
    NameClaimType=“name”
    },
    //通过将所有请求的作用域追加到一个字符串中(用空格分隔)来指定作用域
    Scope=$“{OpenIdConnectScopes.OpenId}{readtaskscope}{writetaskscope}”
    }
    );
    }
    /*
    *在每次调用Azure AD B2C时,检查是否在OWIN上下文中指定了策略(例如配置文件编辑或密码重置策略)。
    *如果是这样,在打电话时使用该策略。另外,不要请求代码(因为不需要代码)。
    */
    专用任务OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification通知)
    {
    var policy=notification.OwinContext.Get(“策略”);
    如果(!string.IsNullOrEmpty(策略)和&!policy.Equals(DefaultPolicy))
    {
    notification.ProtocolMessage.Scope=OpenIdConnectScopes.OpenId;
    notification.ProtocolMessage.ResponseType=OpenIDConnectResponseType.IdToken;
    notification.ProtocolMessage.IssuerAddress=notification.ProtocolMessage.IssuerAddress.ToLower().Replace(DefaultPolicy.ToLower(),policy.ToLower());
    }
    返回Task.FromResult(0);
    }
    /*
    *捕获身份验证中间件接收到的任何故障,并
    
    https://login.microsoftonline.com/{tenant}/oauth2/token