50

WebAPIプロジェクトでCORSサポートを有効にしようとしています。匿名認証を有効にすると、すべて正常に機能しますが、Windows認証と匿名認証を無効にすると、送信されたOPTIONS要求は常に401の不正な応答を返します。それを要求しているサイトはDOMAINにあるので、電話をかけることができるはずですが、Windows認証を無効にせずに問題を回避する方法はありますか?

4

14 に答える 14

42

匿名ユーザーにはOPTIONS動詞のみを許可できます。

<system.web>
  <authentication mode="Windows" />
    <authorization>
      <allow verbs="OPTIONS" users="*"/>
      <deny users="?" />
  </authorization>
</system.web>

W3C仕様によると、ブラウザーはCORSプリフライトからユーザー資格情報を除外します:https ://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html#preflight-request

于 2014-09-15T09:09:40.503 に答える
26

数年後、@dariusrigginsと@lex-liからの回答により、Global.asaxに次のコードを追加することができました。

    public void Application_BeginRequest(object sender, EventArgs e)
    {
        string httpOrigin = Request.Params["HTTP_ORIGIN"];
        if (httpOrigin == null) httpOrigin = "*";
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", httpOrigin);
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Token");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");

        if (Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.StatusCode = 200;
            var httpApplication = sender as HttpApplication;
            httpApplication.CompleteRequest();
        }
    }

httpOriginは実際には許可されたホストのリストで検索されますが、それは複雑なことです。これは、他のすべてのリクエストは検証されますが、オプションは返されるだけであることを意味します。

この質問をありがとう、私はそれなしで失われていたでしょう!

于 2015-09-02T10:56:56.373 に答える
15

MSから:

匿名認証を無効にした場合、IISがすべての要求に対して401を返すように設計されています。Windows認証が有効になっている場合、その場合の401応答には、クライアントが認証ハンドシェイクを開始できるようにするWWW-Authenticateヘッダーが含まれます。次に、顧客が使用しているクライアントがWindows認証を実行できるかどうかが問題になります。

最後に、1つの動詞(この場合はOPTIONS)に匿名アクセスが許可されるようにURLを構成できるかどうかについて根本的な質問があるようですが、他の動詞にはWindows認証が必要です。IISは、単純な構成ではこれをサポートしていません。匿名認証とWindows認証の両方を有効にし、匿名ユーザーへのアクセスを拒否するコンテンツにACLを設定し、問題のURLのハンドラーマッピングを構成して、 URLに関連付けられたファイル。しかし、これを確認するには、それをいじってみる必要があります。

于 2012-05-30T16:25:23.500 に答える
5

これを修正する最も簡単な方法は、条件request_method = ^OPTIONS$を使用して書き換えルールを作成することです。次に、アクションをカスタムレスポンスに設定し、200OKに設定します。その後、すべてのオプションリクエストは401ではなく200で応答します。これにより、CORSの問題が修正されます。

もちろん、正しいクロスオリジンリクエストヘッダーがあることを確認する必要があります。

これにより、統合認証が有効になっている場合に、401で応答するオプション要求(資格情報がない)が停止します。

于 2016-01-21T09:56:53.740 に答える
4

受け入れられた答えは正しいですが、しばらくの間、「iisnodeとnpmcorsモジュールを備えたノード」セットアップを使用してRESTAPIのトラブルシューティングを行っていたため、すべてのユーザーに対して匿名認証を有効にすることに慣れていませんでした。そのノードアプリケーションなので、system.webタグはあまり機能しません。最終的にweb.configに次のように追加されました。

<system.webServer>
<security>
  <requestFiltering>
    <hiddenSegments>
      <add segment="node_modules" />
    </hiddenSegments>
  </requestFiltering>
  <authorization>
    <add accessType="Allow" verbs="OPTIONS" users="?" />
    <add accessType="Deny" verbs="GET, PUT, POST, DELETE" users="?" />
  </authorization>
</security>
</system.webServer>
于 2016-03-18T09:40:16.983 に答える
4

関連する質問:IISがCORSPreflightOPTIONSリクエストをハイジャックする

複数の場所で見つかった回答からの情報をマージします。イントラネットでWindows認証を使用してASP.netページメソッドでCORSを有効にする必要がある場合は、これが機能しているように見えます。に変更を加えないとweb.config、これは機能しません。

これをに追加する必要がありますGlobal.asax

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        string httpOrigin = HttpContext.Current.Request.Params["HTTP_ORIGIN"] ?? HttpContext.Current.Request.Params["ORIGIN"] ?? "*";
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", httpOrigin);
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Token");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");

        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.StatusCode = 200;
            var httpApplication = sender as HttpApplication;
            httpApplication.CompleteRequest();
        }
    }

そしてこれをweb.config

 <system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." 
           verb="*" type="System.Web.Handlers.TransferRequestHandler" 
           preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
于 2019-02-05T23:20:05.297 に答える
4

@dariusrigginsによって提供された答えを拡張します。この投稿を確認してください:Microsoft | 開発者:すべてをまとめる–CORSチュートリアル

IIS構成の場合:

承認ルール

承認ルール

承認段階(または承認イベント)では、CORSプリフライトからの匿名リクエストのみを許可し、他のすべての着信リクエストに認証資格情報が提供されていることを確認する必要があります。これは、承認ルールを通じて実現できます。すべてのユーザーにサイトへのアクセスを許可するデフォルトの承認ルールはすでに適用されており、IISによってデフォルトで提供されます。OPTIONS http動詞を使用するリクエストを送信する場合、匿名ユーザーのみを許可するようにこのルールを変更することから始めます。以下は、この承認ルールのIISでのターゲット構成です。

承認ルールの編集

承認ルールの編集

于 2019-08-16T16:43:15.380 に答える
3

IE 10と11のバグが原因で、今日同じ問題が発生しました。WebApiの代わりにServiceStackを使用していますが、このアプローチも機能します。

  1. IISWebサイトでWindows統合および匿名認証を有効にしました。
  2. ServiceStackパイプラインに一連のフィルターを設定します。
    • CorsおよびOPTIONSリクエストを処理するために、Optionsリクエストで、必要なヘッダーを追加してリクエストを終了します。
    • HttpRequestが認証されているかどうかをチェックするためのフィルター?、
    • などフィルター、

すべてのフィルターを通過した後、サービスを実行します。

CorsFeature.cs

AuthenticateFilter

私のAppHostでは、

appHost.Plugins.Add(new CorsFeature());

appHost.RequestFilters.Add(AuthenticateFilter.Authenticate);

ヘッダーの追加に加えて、OptionsRequestを処理するようにCorsFeatureを変更しました。認証されたリクエストをチェックするために、AuthenticateFilterを使用します。

于 2014-05-14T19:11:56.603 に答える
2

(AngularJSまたはJQueryを使用している場合)私にとってうまくいったのは、クライアントの各リクエストにwithCredentials:trueを追加することです。

$http.get("http://localhost:88/api/tests", {withCredentials :true})

サーバーでCORSを有効にすると、これはnugetのMicrosoft.Owin.Corsを使用して行われ、次のようにスタートアップに追加されます。

public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();

        ConfigureOAuth(app);

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);

    }

参照:

于 2015-12-23T14:43:36.710 に答える
1

私はWebAPIとOWINを使用しており、提案されたすべてのソリューションを試しましたが、機能したのは次のとおりです。

//use it in your startup class
app.Use((context, next) =>
{
    if (context.Request.Headers.Any(k => k.Key.Contains("Origin")) && context.Request.Method == "OPTIONS")
    {
        context.Response.StatusCode = 200;
        context.Response.Headers.Add("Access-Control-Allow-Origin", new string[1] { "ALLOWED_ORIGIN" });
        context.Response.Headers.Add("Access-Control-Allow-Headers", new string[4] { "Origin", "X-Requested-With", "Content-Type", "Accept" });
        context.Response.Headers.Add("Access-Control-Allow-Methods", new string[5] { "GET", "POST", "PUT", "DELETE", "OPTIONS" });
        context.Response.Headers.Add("Access-Control-Allow-Credentials", new string[1] { "true" });

        return context.Response.WriteAsync("");
    }

    return next.Invoke();
});

//this is important! Without it, it didn't work (probably because the middleware was too late)
app.UseStageMarker(PipelineStage.Authenticate);

このコードをOWINスタートアップクラスの1つのどこかに挿入する必要があります。app.UseStageMarker(PipelineStage.Authenticate)プリフライトチェックが失敗したため、電話することが重要です。UseStageMarkerの詳細情報-> https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline

許可されるヘッダーを明示的に定義する必要があることも重要です。*プレースホルダーとして使用すると失敗します。

多分それは誰かを助けます。

于 2017-04-19T12:10:00.653 に答える
1

これはいくつかの可能な解決策(およびその他の質問)を含む古い質問であることを理解していますが、他の誰かがこれに遭遇した場合に備えて、IISCORS1.0は2017年11月の時点で利用可能です。

https://blogs.iis.net/iisteam/introducing-iis-cors-1-0

https://docs.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference

IIS Windowsプラットフォームインストーラー(WPI)からダウンロードできます。これにより、CORS認証の問題の多くが解決されるはずです。楽しみ!

于 2018-08-30T20:20:41.307 に答える
1

このIIS拡張機能(IIS CORSモジュール)は、Windows認証が有効になっているIISホストアプリへの401-不正なプリフライト要求を解決するのに役立ちました。このモジュールをインストールした後、IISRESETを実行し、WebアプリケーションのWeb.configファイルに次を追加しました。

<configuration>
    <configSections>
        <!-- ... (configSections must be the first element!) -->
    </configSections>
    <system.webServer>
        <cors enabled="true">
            <add origin="http://localhost:3000" allowCredentials="true" maxAge="120">
                <allowHeaders allowAllRequestedHeaders="true"/>
                <!-- Added 'allowMethods' just in case. -->
                <allowMethods>
                    <add method="HEAD"/>
                    <add method="GET"/>
                    <add method="POST"/>
                    <add method="PUT"/>
                    <add method="DELETE"/>
                    <add method="OPTIONS"/>
                </allowMethods>
            </add>
        </cors>
    </system.webServer>
</configuration>

ここでは、IISCORSモジュールの構成方法の詳細を確認できます。IISCORSモジュールの使用 を開始します

于 2021-04-04T09:56:31.763 に答える
0
  • IISにIISCORSモジュールをインストールします。

  • WebApiの場合は追加:

public static void Register(HttpConfiguration config)
{
    var cors = new EnableCorsAttribute("*", "*", "*");
    cors.SupportsCredentials = true;
    config.EnableCors(cors);
}
  • 次の行をweb.configに追加します。
  <configuration>
    <system.webServer>
        <cors enabled="true" failUnlistedOrigins="true">
            <add origin="*">
               <allowHeaders allowAllRequestedHeaders="true">
                    <add header="Access-Control-Allow-Origin" />
                    <add header="Access-Control-Allow-Headers" />
                    <add header="Access-Control-Allow-Methods" />
                </allowHeaders>
            </add>
        </cors>
    </system.webServer>
  </configuration>

より詳しい情報。この記事では。

  • xhrFields: {withCredentials: true}ajax呼び出しに追加します。
于 2021-11-07T07:13:22.490 に答える
-1

WebApiConfig.csのEnableCorsAttributeでSupportCredentialsを有効にすると、次のようなトリックが得られました。

public static void Register(HttpConfiguration config)
{        
    //enable cors request just from localhost:15136 
    var cors = new EnableCorsAttribute("http://localhost:15136", "*", "*");
    cors.SupportsCredentials = true;
    config.EnableCors(cors);

    //other stuff
}

https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

javascript({withCredentials :true})から呼び出すときは、必ずクレデンシャルを送信してください

于 2016-11-24T14:21:56.357 に答える