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.

  • 相关阅读:
    Nginx学习高可用
    Nginx安装学习
    Nginx服务器熟悉
    SVN无法连接解决方法
    CentOS 7下搭建SVN服务器&多项目教程
    iframe操作
    Java 微服务架构选型
    vue-cli4.5创建vue项目
    线程间的协作(wait/notify/sleep/yield/join)
    多线程的创建、停止
  • 原文地址:https://www.cnblogs.com/shihao/p/2320680.html
Copyright © 2011-2022 走看看