C# UseOpenIdConnectAuthentication的CORS问题

C# UseOpenIdConnectAuthentication的CORS问题,c#,asp.net-web-api,openid-connect,C#,Asp.net Web Api,Openid Connect,这里Angularjs是前端,WebAPI是中间层。我们正在使用AzureAD OpenID connect进行身份验证。 我面临以下问题。因为我的登录页并没有加载 访问“”处的XMLHttpRequest(从“https%3A%2F%2Flocalhost%3A44300%2F/api/Scorecard/GetServiceNameWithManagers?loginUser”重定向)=xxx@microsoft.com')来自源站的“https%3A%2F%2Flocalhost%3A44

这里Angularjs是前端,WebAPI是中间层。我们正在使用AzureAD OpenID connect进行身份验证。
我面临以下问题。因为我的登录页并没有加载

访问“”处的XMLHttpRequest(从“https%3A%2F%2Flocalhost%3A44300%2F/api/Scorecard/GetServiceNameWithManagers?loginUser”重定向)=xxx@microsoft.com')来自源站的“https%3A%2F%2Flocalhost%3A44300%2F”已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“访问控制允许源站”标头

我做了大量的研究,并在请求和响应时应用了访问控制Allow Origin=*。还应用了app.UseCors(Owin.Cors.CorsOptions.AllowAll); 但到目前为止还没有成功

考虑以下代码,即使用户登录到microsoft站点,AuthorizationCodeReceived委托也不是第一次调用

请注意,此代码不是第一次使用。它会在点击几个按钮(回发)后工作,然后在几分钟后,如果我们运行应用程序,它会抛出CORS飞行前问题。请帮忙

这是我的startup.cs

    public void Configuration(IAppBuilder app)
    {
        app.UseCors(Owin.Cors.CorsOptions.AllowAll);
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies",
            CookieManager = new SystemWebChunkingCookieManager(),              
        });

        //// Bearer token authentication middleware.(Ex: request from web clients,ajax calls able to pass authenticated bearer info)
        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
          new WindowsAzureActiveDirectoryBearerAuthenticationOptions
          {
              TokenValidationParameters = new TokenValidationParameters
              {
                  ValidAudience = ConfigurationManager.AppSettings["ida:Audience"],
                  TokenReplayCache = new TokenReplayCache(new MemoryCacheProvider())
              },
              Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
              Provider = new OAuthBearerAuthenticationProvider
              {
                  OnValidateIdentity = ctx =>
                  {
                      //// Retrieve user roles from the request.                                  
                      var authenticationTicket = ctx.Ticket;
                      if (authenticationTicket.Identity.IsAuthenticated)
                      {
                          ////Use the block when role/user specific authorization needs and to modify the user identity claims based on requirement
                      }

                      return Task.FromResult(0);
                  },
                  OnRequestToken = ctx => { return Task.FromResult(0); }
              }
          });

        //// Non Bearer authentication middleware. (Ex: request secured web api call directly from URL/Web API server scope it self)
        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = ClientId,
                ClientSecret = ConfigurationManager.AppSettings["ida:AppKey"],
                Authority = Authority,
                PostLogoutRedirectUri = PostLogoutRedirectUri,
                AuthenticationMode = AuthenticationMode.Active,
                ResponseType = "code id_token",
                CallbackPath = new PathString("/"),


                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    SecurityTokenValidated = context =>
                    {
                        if (context.AuthenticationTicket.Identity.IsAuthenticated)
                        {
                            ////Use the block when role/user specific authorization needs and to modify the user identity claims based on requirement
                        }

                        return Task.FromResult(0);
                    },
                    AuthorizationCodeReceived = async context =>
                    {
                        var code = context.Code;
                        ClientCredential credential = new ClientCredential(ClientId, Models.ConfigurationData.GraphSecret);
                        string userObjectID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
                        AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectID));
                        Uri uri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
                        AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, uri, credential, GraphResource);
                    },
                    RedirectToIdentityProvider = context =>
                    {

                        if (context.ProtocolMessage.RedirectUri == null)
                        {
                            ////To set the reply/redirect Url based on the request host environment. 
                            ////Hosting env details we get only through the owin context in startup and this is the delegate to set reply URL in OWincontext before the authentication. 
                            string ReplyAddress = context.Request.Scheme + "://" + context.Request.Host + "/";
                            context.ProtocolMessage.RedirectUri = ReplyAddress;
                        }
                        //context.OwinContext.Authentication.User.Identity.IsAuthenticated = true;
                        if (context.OwinContext.Authentication.User.Identity.IsAuthenticated && context.ProtocolMessage.RequestType != IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Logout)
                        {
                            ////To avoid infinite loop of redirections in request if user is authenticated and unauthorized.  
                            context.HandleResponse();
                            context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        }

                        return Task.FromResult(0);
                    }
                },
                TokenValidationParameters = new TokenValidationParameters
                {
                    RoleClaimType = "roles",
                    TokenReplayCache = new TokenReplayCache(new MemoryCacheProvider())
                },
            });
        System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier = System.IdentityModel.Claims.ClaimTypes.NameIdentifier;
    }

在“”处访问XMLHttpRequest(从“https%3A%2F%2Flocalhost%3A44300%2F/api/Scorecard/GetServiceNamxxxManager?loginUser”重定向)=xxx@microsoft.com')来自源站的“https%3A%2F%2Flocalhost%3A44300%2F”已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“访问控制允许源站”标头。

我想您误解了错误消息。它说您的AngularJS应用程序试图向
https://login.microsoftonline.com/xxx-xx-41af-91ab-xxx/oauth2/authorize
和失败,因为这是一个跨原点请求,服务器没有通过在对飞行前请求的响应中返回
访问控制允许原点
头来批准它(HTTP方法选项)


因此,您不能通过向后端添加CORS头来更改它。
授权
不是为XMLHttpRequest请求而设计的-您应该向该URL发出完整的浏览器请求。稍后,浏览器将重定向到
重定向uri
(请求参数值)还有身份验证代码或错误。

VMK,你检查过我的答案了吗?它有帮助吗?或者你用其他方式解决了你的问题了吗?谢谢你的评论。下面检查我的评论暂时修复了如下解决方案…如果Cors源问题触发了捕获块(在angularjs),那么window.open('))几秒钟后关闭窗口并重定向到实际的api。我已经在web api端应用了所有方法。在angualrjs也使用了adal.js,但没有任何效果。这是我为解决此问题所做的唯一愚蠢的修复:(如果有任何解决方案,请告诉我。)