【问题标题】:Authentication and Authorization with ASP.NET Core and Service Stack使用 ASP.NET Core 和服务堆栈进行身份验证和授权
【发布时间】:2017-07-11 21:31:55
【问题描述】:

我有一个 ASP.Net Core MVC Web App,用户需要登录才能从 IdentityServer4 获取 id_token,然后将 id_token 传递给在 ServiceStack 中实现的 webapi 以获取授权码。后续调用webapi会使用授权码。

到目前为止,我所阅读的是 Web 应用程序,它应该使用 openid cookie 令牌 (UseOpenIdConnectAuthentication)。对于 webapi,它应该使用不记名令牌。我的问题是如何将客户端浏览器中的仅 http cookie 令牌作为 http 标头中的不记名令牌传递。由于 cookie 仅是 http,因此 Javascript 无法访问它。另外,ASP.NET Core cookie中间件对cookie进行了加密,这个加密的cookie能否被ServiceStack webapi解密(如果cookie是传给webapi的)?

我的方向正确吗?欢迎提出任何建议。

谢谢

【问题讨论】:

    标签: authentication asp.net-core servicestack identityserver4


    【解决方案1】:

    您可以在此处找到您的场景示例:https://identityserver4.readthedocs.io/en/release/quickstarts/5_hybrid_and_api_access.html

    授权码仅用于从身份服务器获取访问令牌,不用于对 API 进行身份验证。

    以下是流程应该的工作方式:

    1. 用户在 Identity Server 上登录
    2. 您的 MVC 应用程序获得授权码和 id 令牌
      • id 令牌告诉您的 MVC 应用程序用户是谁
    3. 授权码与 API 的身份服务器交换访问令牌和刷新令牌
    4. 现在 MVC 应用可以使用访问令牌从其后端进行 HTTP 调用
    5. 身份验证cookie被创建并返回给用户
    6. 前端将身份验证 cookie 与每个请求一起提交给 MVC 后端,该后端自动验证每个命中 MVC 的请求,然后当您想从那里调用 API 时,按照文档中所示获取它,并将其附加到您的请求

    【讨论】:

    • 感谢您的回复。我想澄清一下,MVC 应用程序客户端(浏览器)将直接调用 webapi,而不是通过 MVC 应用程序,我认为这是该示例正在执行的操作,步骤 6(从那里调用 API)正在执行.是否可以直接调用 webapi,而不是通过 MVC 应用程序。另外,webapi 使用的是没有 ASP.NET Core 的 ServiceStack,它如何解密 ASP.Net Core 加密的 cookie。
    • 该 API 在示例中由 MVC 应用程序的后端调用。那么你需要的可能是使用隐式授权流。而且 cookie 是为您的 MVC 应用程序设计的,无需将其发送到 API。您的前端将需要获取 API 的访问令牌,以便将其附加到 AJAX 请求标头。
    • 对,问题是“前端需要如何获取 API 的访问令牌”?要获取 API 的 access-token,前端需要先将身份传递给 API,对吧? id-token 是干什么用的?但是如果从 MVC App 获得的 id-token 是在 cookie 中加密的,那么如何检索它并将其传递给 API。或者你的意思是API的访问令牌是通过MVC App获得的?
    • 不,id 令牌不适用于 API。您从身份服务器获得访问令牌,其中也包含用户信息。您的 API 检查令牌的签名并从中获取调用用户的信息。
    • 由于您的调用将直接从前端转到 API,这是您所拥有的场景:identityserver4.readthedocs.io/en/release/quickstarts/…
    【解决方案2】:

    我认为您在这里缺少的一点是,一旦用户登录,当您返回客户端应用程序时,您也会在响应中获得访问令牌。如果您使用的是 Hybrid Flow,我们在客户端应用程序上将其配置为

    app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
    {
        AuthenticationScheme = "oidc",
        SignInScheme = "Cookies",
    
        Authority = "http://localhost:5000",
        RequireHttpsMetadata = false,
    
        ClientId = "mvc",
        ClientSecret = "secret",
    
        ResponseType = "code id_token",
        Scope = { "api1", "offline_access" },
    
        GetClaimsFromUserInfoEndpoint = true,
        SaveTokens = true
    }); 
    

    查看我们要求的 ResponseType 代码,即访问代码。因此,您无需再次致电或登录。一旦你想调用你的 api,只需获取类似

    的令牌
    var access_token = await HttpContext.Authentication.GetTokenAsync("access_token");
    
    // call api
    var client = new HttpClient();
    client.SetBearerToken(access_token);
    
    var response = await client.GetAsync("http://localhost:5001/identity");
    if (!response.IsSuccessStatusCode)
    {
        Console.WriteLine(response.StatusCode);
    }
    else
    {
        var content = await response.Content.ReadAsStringAsync();
        Console.WriteLine(JArray.Parse(content));
    }
    

    如果您使用隐式流,您的前端可以使用 oidc-client 库获取访问令牌,并且 user.access_token 将拥有它。

    【讨论】:

    • 如果我错了,请纠正我如果它使用混合响应类型并从 MVC 应用程序获取代码和 id_token,这将是 MVC 应用程序的访问令牌,而不是 webapi 的访问令牌对吧?
    • MVC 应用程序的访问令牌将是您用于访问 Web api 的内容。两者都是一样的。想一想,为什么需要 MVC 应用程序的访问令牌。访问令牌用于 Web api 等安全资源。尝试使用官方文档或@juunas 提供的示例示例。我相信你不会遇到任何问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 2019-07-11
    • 2017-04-15
    相关资源
    最近更新 更多