CORS в Ajax запросе против asp. net веб-форм с авторизацией Identity Server 4 - PullRequest
3 голосов
/ 23 января 2020

В настоящее время я работаю над сайтом, который использует несколько ajax запросов и фреймов для загрузки и поиска данных. Он был построен с использованием C#, ASP. Net веб-форм и jQuery (в основном используется для запросов AJAX) и действует как клиент для решения IdentityServer4 на основе единого входа.

Процесс авторизации / аутентификации от клиента ASP. Net webforms до IdentityServer работает нормально. Однако проблема, с которой я сталкиваюсь, заключается в том, что меня перенаправляют с веб-формы IdentityServer4 на ASP. Net и выполняют поиск на сайте ASP. Net, который включает в себя запрос jQuery AJAX, Я получаю следующую ошибку при просмотре вкладки консоли в веб-браузере ниже.

Доступ к XMLHttpRequest по адресу https://localhost: 44307 / подключить / авторизовать ? '(перенаправлено из' https://localhost: 44304 / ajax / WebRequest.aspx / GetQuoteSearchDetails ') из источника' https://localhost: 44304 'заблокировано политикой CORS: Ответ на предварительный запрос не проходит проверку контроля доступа: в запрашиваемом ресурсе отсутствует заголовок «Access-Control-Allow-Origin»

Я предоставил снимок ошибки, описанной выше здесь для вашего обзора, справки и пояснения.

Ниже приведена настройка клиента ASP. Net Webforms.

    public void Configuration(IAppBuilder app)
    {
      JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();  
      IdentityModelEventSource.ShowPII = true;          
      // For more information on how to configure your application, visit 

      // Fix for Bad Request 400 stemming from too many nonce cookies added to the header which 
      // caused the site to crash. It appears that the authentication cookies were disappearing in the authentication
      // process. Hence the following line of code preserves such cookies from being lost. 

      app.UseKentorOwinCookieSaver();

      app.UseCookieAuthentication(new CookieAuthenticationOptions()
      {               
        AuthenticationType = "Cookies",
        LoginPath = new PathString("/Master/Login")
      });
      JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); //in Identity3 example  https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/Clients/WebFormsClient/Startup.cs
      app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
      {
        AuthenticationType = "oidc",
        Authority = "https://localhost:44307",
        ClientId = "WebformsClient",
        ResponseType = "code id_token",  //OpenIdConnectResponseType.CodeIdTokenToken,
        ClientSecret = "secret",
        Scope = "openid profile",
        RedirectUri = "https://localhost:44304/signin-oidc", //"https://localhost:44319/signin-oidc",
        PostLogoutRedirectUri = "https://localhost:44304/signout-callback-oidc", //"https://localhost:44319/signout-callback-oidc",
        Notifications = new OpenIdConnectAuthenticationNotifications
        {
          AuthenticationFailed = context =>
          {
            context.HandleResponse();
            context.Response.Redirect("/Error?message=" + context.Exception.Message);
            return Task.FromResult(0);
          }
        },
        UseTokenLifetime = false,
        RequireHttpsMetadata = false,
        TokenValidationParameters = new TokenValidationParameters
        {
          NameClaimType = JwtRegisteredClaimNames.GivenName,
          RoleClaimType = ClaimTypes.Role
        },
        //ProtocolValidator = new OpenIdConnectProtocolValidator
        //{
        //    RequireNonce = false
        //},
        SignInAsAuthenticationType = "Cookies",
      });

      app.UseKentorOwinCookieSaver();
        app.UseStageMarker(PipelineStage.Authenticate); //in Identity3 example
      } 

Ниже приведена настройка IdentityServer4 для веб-форм клиент, упомянутый выше.

new Client
{
  ClientId = "WebformsClient",
  ClientName = "Asp.Net Webforms Client",
  AllowedGrantTypes = GrantTypes.Hybrid,
  RequireConsent = false,
  AllowAccessTokensViaBrowser = true,
  AlwaysSendClientClaims = true,
  AlwaysIncludeUserClaimsInIdToken = true, 

  // where to redirect to after login                        
  RedirectUris = new List<string>()
  {
    "https://localhost:44304/signin-oidc"
  },                        

  //// where to redirect to after logout
  PostLogoutRedirectUris = new List<string>()
  {
    "https://localhost:44304/signout-callback-oidc"
  },

  AllowedScopes = new List<string>
  {
    IdentityServerConstants.StandardScopes.OpenId,
    IdentityServerConstants.StandardScopes.Profile
  },

  ClientSecrets =
  {
    new Secret("secret".ToSha256())
  },

  AllowedCorsOrigins = new List<string> {"192.168.6.112"}       
}

Сделав некоторые факты по вышеупомянутой проблеме, связанной с CORS, я попробовал следующие предложения ниже, но пока не испытывал радости.

Добавление настраиваемые заголовки в веб-конфигурации WebformsClient (для краткости усечены)


    <system.webServer>    
      <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="*" />
          <add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS" />
          <add name="Access-Control-Allow-Headers" value="Content-Type, soapaction"/>
        </customHeaders>
      </httpProtocol>
    </system.webServer>

Установка настраиваемых заголовков в обработчике WebformsClient Application_BeginRequeset

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
      //// Preflight request comes with HttpMethod OPTIONS
      if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
      {
        HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        // The following line solves the error message
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
        // If any http headers are shown in preflight error in browser console add them below
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Pragma, Cache-Control, Authorization ");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
      }
    }

O Ни один из AJAX запросов, который обрабатывает запросы и отправляет данные обратно (также добавляя настраиваемые заголовки, чтобы разрешить CORS)

    ajax: {
      beforeSend: function (xhr) {
        xhr.setRequestHeader('Access-Control-Allow-Origin','*');
        xhr.setRequestHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
        xhr.setRequestHeader('Access-Control-Allow-Headers', 'Content-Type, soapaction');
      },
      method: "POST",
      url: "dummyURL",
      contentType: "application/json;charset=utf-8",
      dataType: "json",
      //crossDomain: true,
      xhrFields: {
        withCredentials: true
      },
      //headers : {
      //    "accept": "application/json",
      //    "Access-Control-Allow-Origin":"*"
      //},
      data: function (d) {
        var SearchDetails = new Object();
        var aoData = [];

        // Removed some code for security reasons.

        return JSON.stringify({ SearchDetails: aoData });
      },
      datasrc: ""
    }   

С информацией, которую я предоставил выше, я надеюсь, что кто-нибудь мог бы сбросить некоторые свет в отношении того, что должно быть сделано, и если есть что-то, что я пропустил.

Буду признателен за любые полезные замечания и предложения.

ОБНОВЛЕНИЕ:

Мне удалось решить первоначальную проблему, касающуюся «Доступ- Control-Allow-Origin ', но теперь столкнулся с другой проблемой.

Добавление следующих заголовков ответа в файл web-конфигурации сервера (IdentityServer4) под тегом «System.Webserver», как показано ниже, устранит вышеуказанную проблему. но теперь приводит к другой проблеме, связанной с кодом состояния http 405 BAD METHOD, OPTIONS не разрешено "(см. снимок ниже).

    <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="https://localhost:44304" />
          <add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS" />
          <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, soapaction" />
          <add name="Access-Control-Allow-Credentials" value="true" />
          <add name="Accept" value="application/json" />
        </customHeaders>
    </httpProtocol>

Http code code 405" BAD METHOD: OPTIONS Снимок.

Http status code 405 error snapshot

...