来自桌面应用程序的 .Net MVC 6 授权

.Net MVC 6 Authorization from desktop app

使用项目模板中的样板代码,我创建了一个带有登录名的 .net core 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 的代码是(从 Whosebug 复制粘贴并添加 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; 

//它在这里停止并显示 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 class 具有与 webapp 中相同的属性。

不幸的是它不起作用,HTTP 响应是 400。

问题:

  1. 我的逻辑没问题吧?如果是,你能指出代码哪里错了吗?

  2. 基于 cookie 的身份验证是否可以访问 Restful 网站 api?

  3. 考虑到它是 HTTPS,是否可以用于低流量的网络服务?

  4. 如果没有像 strompath 或 auth0 这样的第三方提供商,有没有更好的方法来做到这一点?

Is my logic OK? If yes, could you point out where is the code wrong?

如果您的 API 期望数据为 JSON,那么您可能必须适当地设置 ContentType header:

http.ContentType = "application/json";

(如果您仍然收到 400 作为状态代码,请检查来自 API 的关于您发送错误内容的任何提示的响应)。

Is cookie based authentication OK to access a Restful web api?

这是可能的,但可能不是最好的方法,特别是来自 non-browser 客户。 现在访问安全 APIs 的一个流行选择是通过 Bearer Tokens。您从身份提供者端点(您的应用程序或第三方提供者,例如 Auth0 或 StormPath)获取令牌,并且在对 [=41] 的每个请求中将该令牌包含在 Authorization header 中=].有关这方面的一些讨论,请参阅 https://auth0.com/blog/cookies-vs-tokens-definitive-guide/

您的 API 必须准备好接受不记名令牌作为授权访问的替代方式。在 .Net Core 的情况下,一些中间件会检查 HTTP header 中的传入令牌,对其进行验证,并设置 ClaimsPrincipal,以便您 Authorize 属性继续按预期工作。

通常令牌 JWTs (Json Web Tokens) 可以检查和调试(它们是签名的,未加密),这是使用 cookie 的更好体验。例如,您可以查看令牌以查看它是否已过期并获取一个新令牌,从而避免 API.

中的错误

Can it be used for a webservice with low trafic volume, given that it will be HTTPS?

它可以,但同样,只有当您无法控制您的 API 来添加对令牌的支持时,才会这样做。

Is there any better way to do it without any 3rd party providers like strompath or auth0?

JWT 格式是开放和标准的。您可能会生成您自己的和 return 它们来自您需要构建的身份验证 API(这将 return 令牌而不是 session cookie)。

获得 JWT 后,Microsoft 会提供一个包,帮助您使用 JWT 令牌保护您的 API:

Install-Package Microsoft.AspNetCore.Authentication.Jwt

但是,身份验证很容易出错。这就是像 Stormpath 或 Auth0 这样的第 3 方供应商将真正派上用场的地方。免责声明:我为 Auth0 工作。