C# 如何对ASP.NETWebAPI 2的WPF客户端请求进行身份验证

C# 如何对ASP.NETWebAPI 2的WPF客户端请求进行身份验证,c#,wpf,asp.net-web-api,asp.net-mvc-5,dotnet-httpclient,C#,Wpf,Asp.net Web Api,Asp.net Mvc 5,Dotnet Httpclient,我刚刚创建了一个ASP.NETMVC5WebAPI项目,并添加了实体框架模型和其他一些东西来让它工作 现在,我需要从WPF客户端应用程序中创建一个简单的对API标准方法的认证请求 ASP.NET MVC 5 Web API代码 [Authorize] [RoutePrefix("api/Account")] public class AccountController : ApiController // GET api/Account/UserInfo [H

我刚刚创建了一个ASP.NETMVC5WebAPI项目,并添加了实体框架模型和其他一些东西来让它工作

现在,我需要从WPF客户端应用程序中创建一个简单的对API标准方法的认证请求

ASP.NET MVC 5 Web API代码

[Authorize]
[RoutePrefix("api/Account")]
public class AccountController : ApiController

        // GET api/Account/UserInfo
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("UserInfo")]
        public UserInfoViewModel GetUserInfo()
        {
            ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);

            return new UserInfoViewModel
            {
                UserName = User.Identity.GetUserName(),
                HasRegistered = externalLogin == null,
                LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null
            };
        }
public partial class MainWindow : Window
{
    HttpClient client = new HttpClient();

    public MainWindow()
    {
        InitializeComponent();

        client.BaseAddress = new Uri("http://localhost:22678/");
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json")); // It  tells the server to send data in JSON format.
    }

    private  void Button_Click(object sender, RoutedEventArgs e)
    {
        Test();
    }

    private async void Test( )
    {
        try
        {
            var response = await client.GetAsync("api/Account/UserInfo");

            response.EnsureSuccessStatusCode(); // Throw on error code.

            var data = await response.Content.ReadAsAsync<UserInfoViewModel>();

        }
        catch (Newtonsoft.Json.JsonException jEx)
        {
            // This exception indicates a problem deserializing the request body.
            MessageBox.Show(jEx.Message);
        }
        catch (HttpRequestException ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {               
        }
    }
}
WPF客户端代码

[Authorize]
[RoutePrefix("api/Account")]
public class AccountController : ApiController

        // GET api/Account/UserInfo
        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("UserInfo")]
        public UserInfoViewModel GetUserInfo()
        {
            ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);

            return new UserInfoViewModel
            {
                UserName = User.Identity.GetUserName(),
                HasRegistered = externalLogin == null,
                LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null
            };
        }
public partial class MainWindow : Window
{
    HttpClient client = new HttpClient();

    public MainWindow()
    {
        InitializeComponent();

        client.BaseAddress = new Uri("http://localhost:22678/");
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json")); // It  tells the server to send data in JSON format.
    }

    private  void Button_Click(object sender, RoutedEventArgs e)
    {
        Test();
    }

    private async void Test( )
    {
        try
        {
            var response = await client.GetAsync("api/Account/UserInfo");

            response.EnsureSuccessStatusCode(); // Throw on error code.

            var data = await response.Content.ReadAsAsync<UserInfoViewModel>();

        }
        catch (Newtonsoft.Json.JsonException jEx)
        {
            // This exception indicates a problem deserializing the request body.
            MessageBox.Show(jEx.Message);
        }
        catch (HttpRequestException ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {               
        }
    }
}
公共部分类主窗口:窗口
{
HttpClient=新的HttpClient();
公共主窗口()
{
初始化组件();
client.BaseAddress=新Uri(“http://localhost:22678/");
client.DefaultRequestHeaders.Accept.Add(
新的MediaTypeWithQualityHeaderValue(“应用程序/json”);//它告诉服务器以json格式发送数据。
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
Test();
}
专用异步无效测试()
{
尝试
{
var response=await client.GetAsync(“api/Account/UserInfo”);
response.EnsureSuccessStatusCode();//抛出错误代码。
var data=wait response.Content.ReadAsAsync();
}
catch(Newtonsoft.Json.JsonException jEx)
{
//此异常表示反序列化请求正文时出现问题。
MessageBox.Show(jEx.Message);
}
捕获(HttpRequestException-ex)
{
MessageBox.Show(例如Message);
}
最后
{               
}
}
}
它似乎正在连接到主机,我得到了正确的错误。没关系

响应状态代码不表示成功:401(未经授权)

主要问题是我不知道如何使用WPF客户端发送用户名和密码

(伙计们,我不是在问我是否必须对它进行加密并在API方法实现上使用Auth Filter。我以后一定会这么做的…)

我听说我必须在标题请求中发送用户名和密码。。。但是我不知道如何使用
HttpClient=new-HttpClient()

谢谢你的提示


另外,我是否已将
HttpClient
替换为
WebClient
,并使用
Task
()?

您可以通过当前登录的用户发送,如下所示:

    var handler = new HttpClientHandler();
    handler.UseDefaultCredentials = true;
    _httpClient = new HttpClient(handler);
然后,您可以创建自己的授权筛选器

public class MyAPIAuthorizationFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        //perform check here, perhaps against AD group, or check a roles based db?
        if(success)
        {
            base.OnActionExecuting(actionContext);
        }
        else
        {
            var msg = string.Format("User {0} attempted to use {1} but is not a member of the AD group.", id, actionContext.Request.Method);
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized)
            {
                Content = new StringContent(msg),
                ReasonPhrase = msg
            });
        }
    }
}
然后对控制器中要保护的每个操作使用[MyAPiaAuthorizationFilter]