从项目模板中使用样板代码我创建了一个带有登录名的.net核心mvc6 webapp。
登录控制器是:
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
LoginViewModel是:
public class LoginViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
我可以从登录网页登录。
我想在桌面.net c#程序中使用此项目中具有[Authorization]属性的控制器(作为API)。为此,我计划从登录控制器获取cookie并使用cookie访问API。
桌面软件获取cookie的代码是(复制粘贴形式StackOverflow并添加了JSON序列化):
private void btnLogin_Click(object sender, EventArgs e)
{
HttpWebRequest http = WebRequest.Create(loginUrl) as HttpWebRequest;
http.KeepAlive = true;
http.Method = "POST";
http.ContentType = "application/x-www-form-urlencoded";
var login = new LoginViewModel();
login.Email = txtUserName.Text;
login.Password = txtPassword.Text;
var postData = new JavaScriptSerializer().Serialize(login);
byte[] dataBytes = UTF8Encoding.UTF8.GetBytes(postData);
http.ContentLength = dataBytes.Length;
using (Stream postStream = http.GetRequestStream())
{
postStream.Write(dataBytes, 0, dataBytes.Length);
}
HttpWebResponse httpResponse = http.GetResponse() as HttpWebResponse;
// IT STOPS HERE WITH HTTP 400
// Probably want to inspect the http.Headers here first
http = WebRequest.Create(authorized) as HttpWebRequest;
http.CookieContainer = new CookieContainer();
http.CookieContainer.Add(httpResponse.Cookies);
HttpWebResponse httpResponse2 = http.GetResponse() as HttpWebResponse;
}
LoginViewModel类具有与webapp中相同的属性。
不幸的是它不起作用,HTTP响应是400。
问题:
我的逻辑好吗?如果是的话,你能指出代码在哪里错了吗?
基于cookie的身份验证是否可以访问Restful web api?
是否可以用于具有低流量的网络服务,因为它将是HTTPS?
有没有更好的方法可以在没有像strompath或auth0这样的第三方提供商的情况下做到这一点?
答案 0 :(得分:2)
我的逻辑好吗?如果是的话,你能指出代码在哪里错了吗?
如果您的API期望数据为JSON,那么您可能必须适当地设置ContentType
标头:
http.ContentType = "application/json";
(如果您仍然以400
作为状态代码,请检查API发送错误的任何提示的响应。
基于cookie的身份验证是否可以访问Restful web api?
有可能,但可能不是最好的方法,特别是非浏览器客户端。
如今访问安全API的一个流行选择是通过Bearer Tokens。您从身份提供者端点(您的应用程序或第三方提供者,如Auth0或StormPath)获取令牌,并在每次API请求时在Authorization
标头中包含该令牌。有关此问题的讨论,请参阅https://auth0.com/blog/cookies-vs-tokens-definitive-guide/。
您的API必须准备好接受承载令牌作为授权访问的替代方式。在.Net Core的情况下,一些中间件会检查HTTP头中的传入令牌,验证它,并设置ClaimsPrincipal,以便Authorize
属性保持按预期工作。
通常令牌JWTs (Json Web Tokens)可以检查和调试(它们是签名的,而不是加密的),这是使用cookie的更好体验。例如,您可以查看令牌以查看它是否已过期并获取新令牌,从而避免来自API的错误。
是否可以用于具有低流量的网络服务,因为它将是HTTPS?
但是,只有当您无法控制API以添加对令牌的支持时,才会这样做。
有没有更好的方法可以在没有像strompath或auth0这样的第三方提供商的情况下做到这一点?
JWT格式是开放和标准的。您可能会生成自己的所有者并从您需要构建的身份验证API返回它们(这将返回令牌而不是会话cookie)。
拥有JWT后,Microsoft提供了一个软件包,可以帮助您使用JWT令牌保护您的API:
Install-Package Microsoft.AspNetCore.Authentication.Jwt
然而,身份验证很容易出错。这就是Stormpath或Auth0等第三方提供商真正得心应手的地方。免责声明:我为Auth0工作。