【问题标题】:How to add FormsAuthentication cookie to HttpClient HttpRequestMessage如何将 FormsAuthentication cookie 添加到 HttpClient HttpRequestMessage
【发布时间】:2012-11-30 09:37:42
【问题描述】:

我正在尝试通过调用 FormsAuthentication.SetAuthCookie("someUser", false);
在集成测试中进行身份验证 之后我确实需要调用 WebAPI 并且不会收到未经授权的异常,因为我已经应用了授权属性。 我正在使用此代码创建身份验证 cookie:

var cookie = FormsAuthentication.GetAuthCookie(name, rememberMe);
    var ticket = FormsAuthentication.Decrypt(cookie.Value);

    var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration,
        ticket.IsPersistent, userData.ToJson(), ticket.CookiePath);
    var encTicket = FormsAuthentication.Encrypt(newTicket);

    /// Use existing cookie. Could create new one but would have to copy settings over...
    cookie.Value = encTicket;

现在我想将此 cookie 添加到新 HttpClient 中的 HttpRequestMessage 并在集成测试中将其与我的常规请求一起发送。

我不知道如何将该身份验证 cookie 添加到 HttpRequestMessage ?

【问题讨论】:

    标签: asp.net asp.net-mvc unit-testing asp.net-web-api integration-testing


    【解决方案1】:

    要操作 cookie,您需要使用 WebRequestHandlerHttpClient。例如,

     var handler = new WebRequestHandler();
     var client = new HttpClient(handler);
     // use handler to configure request such as add cookies to send to server
    

    CookieContainer 属性将允许访问 cookie 集合。

    另外,我怀疑在客户端创建 FormsAuthentication cookie 是否可行。客户端/服务器都需要相同的加密密钥。最好的方法是重放实际 Web API 的登录请求 - 很可能,这将是一个 POST 以使用用户凭据登录页面。使用 Fiddler 等工具在浏览器上观察相同的内容,并在您的 http 客户端中构造相同的请求。

    【讨论】:

      【解决方案2】:

      晚了将近 6 年,但仍然可能会有所帮助。基于此的解决方案: https://blogs.taiga.nl/martijn/2016/03/10/asp-net-web-api-owin-authenticated-integration-tests-without-authorization-server/

      首先,在创建 Owin TestServer 时,您必须创建 DataProtector:

          private readonly TestServer _testServer;
          public IDataProtector DataProtector { get; private set; }
      
          public Server(OwinStartup startupConfig)
          {
              _testServer = TestServer.Create(builder =>
              {
                  DataProtector = builder.CreateDataProtector(
                      typeof(CookieAuthenticationMiddleware).FullName, DefaultAuthenticationTypes.ApplicationCookie, "v1");
      
                  startupConfig.Configuration(builder);
              });
          }
      

      然后像这样生成cookie(使用上一步创建的DataProtector):

          public string GeterateCookie()
          {
              var claims = new List<Claim>
              {
                  new Claim(ClaimTypes.Role, "your-role"),
                  new Claim(ClaimTypes.UserData, "user-data"),
                  new Claim(ClaimTypes.Name, "your-name")
              };
      
              var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);
      
              var tdf = new TicketDataFormat(DataProtector);
              var ticket = new AuthenticationTicket(identity, new AuthenticationProperties {ExpiresUtc = DateTime.UtcNow.AddHours(1)});
      
              var protectedCookieValue = tdf.Protect(ticket);
      
              var cookie = new CookieHeaderValue("yourCookie", protectedCookieValue)
              {
                  Path = "/",
                  HttpOnly = true
              };
      
              return cookie.ToString();
          }
      

      确保设置所需的声明,根据提供给 UseCookieAuthentication 方法的设置初始化 ClaimsIdentity,并设置正确的 CookieName。

      最后一步是将 CookieHeader 添加到您的请求中:

          public Task<HttpResponseMessage> RequestAsync(HttpRequestMessage request)
          {
              request.Headers.Add("cookie", GenerateCookie());
              return _client.SendAsync(request);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多