繁体   English   中英

从WPF客户端访问安全的Web API

[英]Accessing a secure Web API from a WPF client

我有一个为CORS配置的Web API项目,并在其中一个APIController上实现[Authorize]。 当我删除[Authorize]时,我可以从WPF客户端访问API,但是当它到位时,调用似乎丢失了。 这就是我设置的请求令牌。

在后面的WPF代码中

    internal void RefreshRecentFilesList()
    {
        //Get the token
        var token = GetAPIToken(email, password, "http://localhost:50006").Result;
        MessageBox.Show(token);
    }

    private static async Task<string> GetAPIToken(string userName, string password, string apiBaseUri)
    {
        using (var client = new HttpClient())
        {
            //setup client
            client.BaseAddress = new Uri(apiBaseUri);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token.AccessToken);

            //setup login data
            var formContent = new FormUrlEncodedContent(new[]
             {
             new KeyValuePair<string, string>("grant_type", "password"), 
             new KeyValuePair<string, string>("username", userName), 
             new KeyValuePair<string, string>("password", password), 
             });

            //send request
            HttpResponseMessage responseMessage = await client.PostAsync("/Token", formContent);

            //get access token from response body
            var responseJson = await responseMessage.Content.ReadAsStringAsync();
            var jObject = JObject.Parse(responseJson);
            return jObject.GetValue("access_token").ToString();
        }
    }

在Web API项目WebAPIConfig.cs中

        //Enable CORS
        var cors = new EnableCorsAttribute("*", "*", "GET");
        config.EnableCors(cors);

在API控制器中

    [HttpGet]
    //[Authorize]
    public List<FileInfo> GetFileTypes()
    {
        List<FileInfo> fileInfos = new List<FileInfo>();
        ...

在StartAuth.cs中

public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // Configure the application for OAuth based flow
        PublicClientId = "self";
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            // In production mode set AllowInsecureHttp = false
            AllowInsecureHttp = true
        };

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);

当我运行WPF并逐步执行代码时,它将转到发送请求行,然后挂起。

有人能指出我正确的方向吗?

非常感谢

我认为您的问题的主要候选人是这一行:

var token = GetAPIToken(email, password, "http://localhost:50006").Result;

您正在调用async方法,然后您正在等待其结果同步:这将导致死锁。 永远不要那样做。

相反,将您的方法(和整个调用堆栈)异步。 如果你在WPF中,你几乎肯定会从某种事件处理程序回调中调用此方法。 那些回调支持async (即使它们必须返回void )。

将代码更改为类似于此的代码,然后再试一次(假设Form_Load是一个事件处理程序回调):

private async void Form_Load(object sender, EventArgs e)
{
    await RefreshRecentFilesList();
}

internal async Task RefreshRecentFilesList()
{
    //Get the token
    var token = await GetAPIToken(email, password, "http://localhost:50006");
    MessageBox.Show(token);
}

参考文献:
为什么这个异步操作会挂起?
如何从C#中的同步方法调用异步方法?

补充Federico Dipuma解决方案是使用构造函数调用Form_Load

this.Loaded += new RoutedEventHandler(Form_Load);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM