【问题标题】:Using .Net Core Identity with Multiple .Net Core Web Applications through an API?通过 API 将 .Net Core Identity 与多个 .Net Core Web 应用程序一起使用?
【发布时间】:2019-01-19 04:05:03
【问题描述】:

我目前在一个解决方案中拥有两个 Web 项目(以及各种类库)。

Web 项目 1 已将 Identity 配置为通过 Web api 登录:

[HttpPost]
    public async Task<IActionResult> Login([FromBody] LoginModel loginModel)
    {
        var res = await _authService.LoginAsync(loginModel.Username, loginModel.Password, loginModel.Persist);
        var data = new APIResult(res, _authService.CurrentErrors);
        return Ok(data);
    }

_authService.LoginAsync() 最终使用 _signInManager.PasswordSignInAsync() 使用 Identity 登录。

使用 Swagger 进行测试,用户已登录,我可以使用 IHttpContextAccessor 访问它,一切正常。

Web 项目 2 是一个 .Net Core Web 应用程序,仅提供视图服务,这些视图具有从 Web 项目 1 调用 API 的 javascript。在登录的情况下,如下所示:

$("#loginBtn").click(function () {
    startLoginBtnLoading();
    var loginModel = {
        Username: $("#loginUsernameTxt").val(),
        Password: $("#loginPasswordTxt").val(),
        Persist: $("#loginPersistChk").is(":checked")
    };
    $.ajax({
        type: 'POST',
        url: '@AuthUrl.LoginUrl',
        contentType: 'application/json; charset=UTF-8',
        data: JSON.stringify(loginModel),
        success: function (result) {
            if (result.success) {
                toastr.success("Login was successful.", "Success");
                $("#loginModal").modal('hide');
                $.event.trigger({ type: "login", time: new Date() });
            }
            else {
                $.each(result.errors, function (ix, ob) {
                    toastr.error(ob, "Error");
                });
            }
            endLoginBtnLoading();
        }
    });
});

这成功调用了我的 API 并允许登录(因为我已将 CORS 设置为允许一切)。但是,HttpContext 不会在 API 调用之间停留,所以当我下次调用我的 API 并检查 HttpContext.User 时,我不再经过身份验证。

我不知道如何通过 API 登录并在下次调用 API 时保持会话而不将其移动到同一个项目中?

【问题讨论】:

  • 您应该查看单点登录解决方案,该解决方案可让您使用相同的登录名登录多个应用程序。 Identity Server 4 是 Microsoft 推荐的。然后您将拥有一个授权服务器应用程序,并且您的两个 MVC 应用程序通过同一台服务器进行身份验证。

标签: c# asp.net-core


【解决方案1】:

这是不可能的。

您正在从客户端调用登录服务。第一个登录 API 将帮助用户登录,它会在第一个应用程序中生成 HTTP 上下文。

请注意,会话状态是一种服务器端状态存储机制。

在身份验证之后,登录 API 可能会发送一个 cookie(在您的代码中未显示)。该 cookie 或该 cookie 中的某种令牌用于识别与该用户对应的服务器端会话状态。

您的登录 API 编写的 cookie 将包含一些 URL,这些 URL 可以用来发送该 cookie。

因此,首先,浏览器可能不会将该 cookie 发送到您的第二个 API。

即使您明确地传递它,因为会话状态是服务器端存储,而 cookie 正在从执行登录的服务器识别会话状态。

解决此问题的一种方法是 - 使用 OWIN/OIDC/OAuth 并让您的身份服务器执行您的登录操作。如果您使用它,它将负责为需要登录的 API 生成和填充服务器端状态。

我希望这会有所帮助。

编辑:您可以refer this blog 说明如何使用 OWIN 创建身份验证 API。

【讨论】:

  • 我相信从 API 项目中存储了一个 cookie,并且它可能没有与来自其他站点的请求一起发送关于在哪里寻找有关实施 Oauth 的良好信息的任何建议?
  • @AlexAshmore - 这也是我所怀疑的。您可以使用 Fiddler 原始请求来验证这一点。还有一件事 - 您还可以检查 cookie 的路径属性。如果路径与下一个 URL 不匹配,则 cookie 不会发送到服务器。
  • 我已经安装了 fiddler 并且登录响应正在设置一个 cookie,但是稍后不会发送 cookie。我注意到你提到的路径,它也在那里:path=/;安全的;同一站点=松懈; httponly 我不完全确定如何让 cookie 与未来的请求一起发送!
  • @AlexAshmore:这就是我建议阅读有关 OIDC 和 OAUTH 的地方。这些协议可帮助您实现此功能 - 将登录作为单独的应用程序,将业务功能作为单独的应用程序。
  • @AlexAshmore 在我的回答中添加了 URL。如果您使用的是 asp.net web api(不是 .net 核心),那么您可以使用该博客中的内容来创建登录 API。
猜你喜欢
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2020-06-14
相关资源
最近更新 更多