0
votes

Here Angularjs is front end and Web API is middle tier. we are using AzureAD OpenID connect for Authentication.
I'm facing following issue. because of the my landing page is not loading

Access to XMLHttpRequest at 'https://login.microsoftonline.com/xx-86f1-41af-91ab-xxx/oauth2/authorize?client_id=xxxx1&response_mode=form_post&response_type=code%20id_token&scope=openid%20profile&state=OpenIdConnect.AuthenticationPropertiesxxxxx&noncexxxxx&redirect_uri=https%3A%2F%2Flocalhost%3A44300%2F&x-client-SKU=ID_NET451&x-client-ver=5.2.1.0' (redirected from 'https%3A%2F%2Flocalhost%3A44300%2F/api/Scorecard/[email protected]') from origin 'https%3A%2F%2Flocalhost%3A44300%2F' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I've done lot of research and applied Access-Control-Allow-Origin =* at Request and response. also applied app.UseCors(Owin.Cors.CorsOptions.AllowAll); but so far no success.

consider following code, AuthorizationCodeReceived delegate is not invoking very first time even though the user is logged in to microsoft site.

Please be noted, this code is not working very first time. It will work after few button clicks (postbacks) and then after few minutes if we run the application it's throws CORS preflight issue. Please help.

This is my 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;
    }

Access to XMLHttpRequest at 'https://login.microsoftonline.com/xx-86f1-41af-91ab-xxx/oauth2/authorize?client_id=xxxx1&response_mode=form_post&response_type=code%20id_token&scope=openid%20profile&state=OpenIdConnect.AuthenticationPropertiesxxxxx&noncexxxxx&redirect_uri=https%3A%2F%2Flocalhost%3A44300%2F&x-client-SKU=ID_NET451&x-client-ver=5.2.1.0' (redirected from 'https%3A%2F%2Flocalhost%3A44300%2F/api/Scorecard/[email protected]') from origin 'https%3A%2F%2Flocalhost%3A44300%2F' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

1
VMK, have you checked my answer? Did it help or did you solve your problem in some other way?Ján Halaša
Thanks for the comments. check my comments belowVMK

1 Answers

1
votes

I think you misunderstood the error message. It says that your AngularJS application was trying to make a request to https://login.microsoftonline.com/xxx-xx-41af-91ab-xxx/oauth2/authorize and failed, because it was a cross-origin request and the server didn't approve it by returning the Access-Control-Allow-Origin header in a response to preflight request (HTTP method OPTIONS).

So you cannot change it by adding CORS headers to your backend. The authorize is not designed to be called by XMLHttpRequest requests - you are supposed to make a full browser request to that URL. Later, the browser will be redirected to redirect_uri (the request parameter value) along with an auth code or an error.