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.

  • 相关阅读:
    TP-LINK,TL-WR885路由器无线桥接方法
    python3 urllib.request.Request的用法
    requests模块
    python3中引入扩展包时的几个注意事项
    Flask-sqlacodegen之ORM操作
    mysql ERROR 1049 (42000): Unknown database '******' ”错误处理办法
    Python各种包下载路径
    python在Apache中的部署
    Python3 基于 Nginx或Apache 部署 Django 项目
    Python如何发布程序
  • 原文地址:https://www.cnblogs.com/shihao/p/2320680.html
Copyright © 2011-2022 走看看