How to authenticate WPF Client request to ASP .NET

2019-03-15 23:12发布

I just created an ASP .NET MVC 5 Web API project and added the Entity Framework model and other things to get it working with ASP. NET Identity.

enter image description here

Now I need to create a simple authenticated request to the standard method of that API out there from the WPF Client app.

ASP .NET MVC 5 Web API code

[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
            };
        }

WPF Client code

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
        {               
        }
    }
}

It seems like it is connecting to the host and I am getting the correct error. That is ok.

Response status code does not indicate success: 401 (Unauthorized).

The main problem that I am not sure how to send username and password using WPF Client...

(Guys, I am not asking whether I have to encrypt it and use Auth Filter over API method implementations. I will do this for sure later...)

I heard that I have to send username and password in the header request... but I don't know how it can be done by using HttpClient client = new HttpClient();

Thanks for any clue!

P.S. Have I replace HttpClient with WebClient and use Task (Unable to authenticate to ASP.NET Web Api service with HttpClient)?

1条回答
The star\"
2楼-- · 2019-03-15 23:44

You can send over the current logged on user like so:

    var handler = new HttpClientHandler();
    handler.UseDefaultCredentials = true;
    _httpClient = new HttpClient(handler);

then you can create your own authorization filter

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
            });
        }
    }
}

then use [MyAPIAuthorizationFilter] on each action in your controller that you want to secure.

查看更多
登录 后发表回答