zoukankan      html  css  js  c++  java
  • Mixing Integrated Authentication and Anonymous Authentication with PreAuthenticated = true doesn’t work

    This StackOverflow question indicate that it is half a bug and half a feature, but that it sure as hell looks like a bug to me.

    Let us assume that we have a couple of endpoints in our application, called http://localhost:8080/secure and http://localhost:8080/public. As you can imagine, the secure endpoint is… well, secure, and requires authentication. The public endpoint does not.

    We want to optimize the number of request we make, so we specify PreAuthenticated = true; And that is where all hell break lose.

    The problem is that it appears that when using request with entity body (in other words, PUT / POST) with PreAuthenticate = true, the .NET framework will issue a PUT / POST request with empty body to the server. Presumably to get the 401 authentication information. At that point, if the endpoint that it happened to have reached is public, it will be accepted as a standard request, and processing will be tried. The problem here is that it has an empty body, so that has a very strong likelihood of failing.

    This error cost me a day and a half or so. Here is the full repro:

    static void Main() {     new Thread(Server)     {         IsBackground = true     }.Start();      Thread.Sleep(500); // let the server start      bool secure = false;     while (true)     {         secure = !secure;         Console.Write("Sending: ");         var str = new string('a', 621);         var req = WebRequest.Create(secure ? "http://localhost:8080/secure" : "http://localhost:8080/public");         req.Method = "PUT";          var byteCount = Encoding.UTF8.GetByteCount(str);         req.UseDefaultCredentials = true;         req.Credentials = CredentialCache.DefaultCredentials;         req.PreAuthenticate = true;         req.ContentLength = byteCount;          using(var stream = req.GetRequestStream())         {             var bytes = Encoding.UTF8.GetBytes(str);             stream.Write(bytes, 0, bytes.Length);             stream.Flush();         }          req.GetResponse().Close();      }  }

    And the server code:

    public static void Server() {     var listener = new HttpListener();     listener.Prefixes.Add("http://+:8080/");     listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication | AuthenticationSchemes.Anonymous;     listener.AuthenticationSchemeSelectorDelegate = request =>     {          return request.RawUrl.Contains("public") ? AuthenticationSchemes.Anonymous : AuthenticationSchemes.IntegratedWindowsAuthentication;     };      listener.Start();      while (true)     {         var context = listener.GetContext();         Console.WriteLine(context.User != null ? context.User.Identity.Name : "Anonymous");         using(var reader = new StreamReader(context.Request.InputStream))         {             var readToEnd = reader.ReadToEnd();             if(string.IsNullOrEmpty(readToEnd))             {                 Console.WriteLine("WTF?!");                 Environment.Exit(1);             }         }          context.Response.StatusCode = 200;         context.Response.Close();     } } 

    If we remove pre authenticate is set to false, everything works, but then we have twice as many requests. The annoying thing is that if it would be trying to authenticate to a public endpoint, nothing would happen, if it were sending the bloody entity body along as well.

    This is quite annoying.

  • 相关阅读:
    java多线程--定时器Timer的使用
    java多线程--线程池的使用
    java多线程--多线程基础小结
    java基础--java.util.Date类型小结
    onClickRow 事件
    C#里的SubString和Convert.ToDateTime
    jquery+easyui开发、培训文档
    Jquery函数大全
    前端最全的 API 集锦
    17个CSS知识点整理
  • 原文地址:https://www.cnblogs.com/shihao/p/2320680.html
Copyright © 2011-2022 走看看