我有一个为CORS配置的Web API项目,并在其中一个APIController上实现[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并逐步执行代码时,它会转到发送请求行,然后挂起。
有人能指出我正确的方向吗?
非常感谢
答案 0 :(得分:3)
我认为您问题的主要候选人是这一行:
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);
}
参考文献:
Why does this async action hang?
How to call asynchronous method from synchronous method in C#?
答案 1 :(得分:0)
this.Loaded += new RoutedEventHandler(Form_Load);