HttpClient 调用Form验证下的WepApi


开始Form认证,拒绝匿名登录

 
    
    
    
      
    
    
      
    
  

 //认证对象实体

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace WebApi.Models
{
public class Credential
{
    [DisplayName("用户名")]
    [Required]
    public string UserName { get; set; }

    [DisplayName("密码")]
    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }
}
}

账号验证Controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Mvc;
using System.Web.Security;
using WebApi.Models;

namespace WebApi.Controllers
{
public class AccountController : Controller
{
    static Dictionary userAccounts;

    static AccountController()
    {
        userAccounts = new Dictionary(StringComparer.OrdinalIgnoreCase);
        userAccounts.Add("Foo","Password");
        userAccounts.Add("Bar","Password");
        userAccounts.Add("Baz","Password");
    }

 
    public ActionResult Login()
    {
        return View(new Credential());
    }
    [HttpPost]
    public ActionResult Login(Credential loginInfo, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(); 
        }
        string password;
        if (userAccounts.TryGetValue(loginInfo.UserName, out password))
        {
            if (password == loginInfo.Password)
            {
                FormsAuthentication.SetAuthCookie(loginInfo.UserName, false);
                if(string.IsNullOrEmpty(returnUrl))
                {
                    return new HttpStatusCodeResult(HttpStatusCode.OK);
                }
                return Redirect(returnUrl);
            }
            ModelState.AddModelError("Password", "密码不正确");
        }
        else
        {
            ModelState.AddModelError("UserName", "用户名不存在");
        }
        return View();
    }
}
}

最关键的调用代码,首先验证账号,获取Server 添加Header的Cookie

然后本地http请求,添加之前请求回来的cookie value。

验证结果是获取Cookie Value,可以模拟Form请求

同时通过FormUrlEncodedContent模拟application/x-www-form-urlencoded对主题内容进行编码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {

            string token = GetSecurityToken("Foo", "Password", "http://localhost:2303/account/login", ".ASPXAUTH");
            string address = "http://localhost:2303/api/demo";
            if (!string.IsNullOrEmpty(token))
            {
                HttpClientHandler handler = new HttpClientHandler { CookieContainer = new CookieContainer() };
                handler.CookieContainer.Add(new Uri(address), new Cookie(".ASPXAUTH", token));
                using (HttpClient httpClient = new HttpClient(handler))
                {
                    HttpResponseMessage response = httpClient.GetAsync(address).Result;
                    IEnumerable userNames = response.Content.ReadAsAsync>().Result;
                    foreach (string userName in userNames)
                    {
                        Console.WriteLine(userName);
                    }
                }
            }
            Console.ReadKey();
        }

        private static string GetSecurityToken(string userName, string password, string url, string cookieName)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                Dictionary credential = new Dictionary();
                credential.Add("UserName", userName);
                credential.Add("Password", password);
                HttpResponseMessage response = httpClient.PostAsync(url, new FormUrlEncodedContent(credential)).Result;
                IEnumerable cookies;
                if (response.Headers.TryGetValues("Set-Cookie", out cookies))
                {
                    string token = cookies.FirstOrDefault(value => value.StartsWith(cookieName));
                    if (null == token)
                    {
                        return null;
                    }
                    return token.Split(';')[0].Substring(cookieName.Length + 1);
                }
                return null;
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Web;
using System.Web.Http;

namespace WebApi.Controllers
{
    public class DemoController : ApiController
    {
        public IEnumerable GetUsers()
        {
            yield return HttpContext.Current.User.Identity.Name;
            yield return Thread.CurrentPrincipal.Identity.Name;
            yield return this.User.Identity.Name;
        }
    }
}