如何将FormsAuthentication cookie添加到HttpClient HttpRequestMessage

时间:2012-11-30 09:37:42

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

我试图通过调用FormsAuthentication.SetAuthCookie(“someUser”,false)来验证内部集成测试;
之后我需要调用WebAPI并且不会收到未经授权的异常,因为我已经应用了授权属性。 我正在使用此代码创建auth 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中,并在集成测试中使用我的常规请求发送它。

我不知道如何将该auth cookie添加到HttpRequestMessage?

2 个答案:

答案 0 :(得分:4)

要操纵Cookie,您需要使用WebRequestHandlerHttpClient。例如,

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

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

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

答案 1 :(得分:0)

晚了将近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);
    }