So aktivieren Sie die beiden CORS-support-und NTLM-Authentifizierung

Habe ich eine self-hosted-c# - console-web-API. It-Dienstleistungen, mehrere web-Anwendungen mit AngularJS zum durchführen von asynchronen http-requests. Es muss sowohl CORS-support-und NTLM-Authentifizierung.

Momentan habe ich beide aktiviert sind, aber es scheint, dass die Art und Weise, dass ich Sie umgesetzt bewirkt, dass Sie sich selbst aufheben. Ich glaube, das ist das Gehäuse von meinem ersten 401-Antwort vom server. Dies führt in der Regel eine Authentifizierung handshake zwischen den beiden, aber es bei der Suche in Fiddler, diese erste 401-Antwort fehlt ein Access-Control-Allow-Origin " - tag, und dies bewirkt, dass der browser nach verlassen der Handschlag. Ich habe eine Anwendung und den gleichen Hostnamen deaktivieren, um die Notwendigkeit für CORS, und der handshake funktioniert perfekt. Ich habe deaktiviert die NTLM-Authentifizierung durch den Austausch meiner custom NtlmSelfHostConfiguration mit dem original HttpSelfHostConfiguration, und die Access-Control-Allow-Origin " - tag führt perfekt zu ermöglichen CORS. es ist nur, wenn Sie aktiv sind, dass Dinge nicht funktionieren.

UPDATE: ich setzte einen Breakpoint in meinem CorsHandle auf eine Anforderung, die nicht benötigt werden, nur um sicherzustellen, dass der webserver wirklich nennen es während der Verwendung der NtlmSelfHostConfiguration, und es war erfolgreich treffen. Ich wollte nur sicherstellen, dass es war nichts in der NtlmSelfHostConfiguration, die physisch verhindert die Corshandle, jemals aufgerufen wird. Hat alles Prima funktioniert, Es scheint definitiv, dass ich einen Weg finden, rufen Sie CorsHandle auch auf Anfragen, die zum fehlschlagen der Authentifizierung.

Hier ist meine Umsetzung:

Programm.cs:

using System.Web.Http;
using System.Web.Http.Validation.Providers;
using System.Web.Http.SelfHost;
namespace DCMAPI
{
    class Program
    {
        static void Main(string[] args)
        {
            string BaseAddress = "http://localhost:8080/";

            //NtlmSelfHostConfiguration is defined in HttpSelfHostConfiguration.cs  
            //it inherits from HttpSelfHostConfiguration 
            //and enables Ntlm Authentication.

            var config = new NtlmSelfHostConfiguration(BaseAddress);

            config.Routes.MapHttpRoute(
                "API Default",
                "api/{controller}/{id}", 
                new { id = RouteParameter.Optional });

            //CorsHandler is also defined in CorsHandler.cs.  It is what enables CORS

            config.MessageHandlers.Add(new CorsHandler());

            var appXmlType =
            config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault
                (t => t.MediaType == "application/xml");
            config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);                   

            config.Services.RemoveAll
                (typeof(System.Web.Http.Validation.ModelValidatorProvider),
                v => v is InvalidModelValidatorProvider);

            using (HttpSelfHostServer server = new HttpSelfHostServer(config))
            {
                server.OpenAsync().Wait();
                Console.WriteLine("running");
                Console.ReadLine();
            }

        }
    }
}

NtlmSelfHostConfiguration.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.SelfHost;
using System.Web.Http.SelfHost.Channels;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace DCMAPI
{
    public class NtlmSelfHostConfiguration : HttpSelfHostConfiguration
    {
        public NtlmSelfHostConfiguration(string baseAddress)
            : base(baseAddress)
        { }

        public NtlmSelfHostConfiguration(Uri baseAddress)
            : base(baseAddress)
        { }

        protected override BindingParameterCollection OnConfigureBinding
            (HttpBinding httpBinding)
        {
            httpBinding.Security.Mode =
                HttpBindingSecurityMode.TransportCredentialOnly;

            httpBinding.Security.Transport.ClientCredentialType =
                HttpClientCredentialType.Ntlm;

            return base.OnConfigureBinding(httpBinding);
        }
    }
}

CorsHandle.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;
using System.Net;

namespace DCMAPI
{
    public class CorsHandler : DelegatingHandler
    {
        const string Origin = "Origin";
        const string AccessControlRequestMethod = "Access-Control-Request-Method";
        const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

        protected override Task<HttpResponseMessage> SendAsync
            (HttpRequestMessage request, CancellationToken cancellationToken)
        {

            bool isCorsRequest = request.Headers.Contains(Origin);
            bool isPreflightRequest = request.Method == HttpMethod.Options;
            if (isCorsRequest)
            {

                if (isPreflightRequest)
                {
                    HttpResponseMessage response = 
                        new HttpResponseMessage(HttpStatusCode.OK);

                    response.Headers.Add(AccessControlAllowOrigin,
                        request.Headers.GetValues(Origin).First());

                    string accessControlRequestMethod =
                        request.Headers.GetValues(AccessControlRequestMethod)
                        .FirstOrDefault();
                    if (accessControlRequestMethod != null)
                    {
                        response.Headers.Add(
                            AccessControlAllowMethods, accessControlRequestMethod);
                    }

                    string requestedHeaders = string.Join(", ",
                        request.Headers.GetValues(AccessControlRequestHeaders));
                    if (!string.IsNullOrEmpty(requestedHeaders))
                    {
                        response.Headers.Add(AccessControlAllowHeaders,
                            requestedHeaders);
                    }

                    TaskCompletionSource<HttpResponseMessage> tcs = 
                        new TaskCompletionSource<HttpResponseMessage>();
                    tcs.SetResult(response);
                    return tcs.Task;
                }
                else
                {
                    return base.SendAsync(request,
                        cancellationToken).ContinueWith<HttpResponseMessage>(t =>
                    {
                        HttpResponseMessage resp = t.Result;
                        resp.Headers.Add(
                            AccessControlAllowOrigin,
                            request.Headers.GetValues(Origin).First());
                        return resp;
                    });
                }
            }
            else
            {
                return base.SendAsync(request, cancellationToken);
            }
        }
    }
}
  • Kann nicht kommentieren auf Ihre eigentliche Frage geht, sondern um eine abgeschlossene Ergebnis Sie kann einfach mit Task.FromResult<T> anstatt Herumspielen mit TaskCompletionSource<T>
  • Möchten Sie vielleicht Access-Control-Allow-Credentials: true in Ihrem CORS Ressource als gut. Sie ermöglicht, dass cookies gesendet werden.
  • Die folgende Antwort könnte helfen: stackoverflow.com/a/15734032/107250
InformationsquelleAutor JHixson | 2013-04-28
Schreibe einen Kommentar