【问题标题】:IdentityServer4 - user permissions on the APIIdentityServer4 - API 上的用户权限
【发布时间】:2017-09-08 08:25:29
【问题描述】:

我目前正在设置一个带有 Web API 和 MVC UI 的新项目(最终也会有一个可以与相同 API 对话的移动 UI)。

所以,我有以下计划:

  1. 用户导航到 MVC UI,将他们带到 IdentityServer4 服务器以登录或注册
  2. 然后将 IdentityServer 用户添加到数据库中应用程序自己的用户表中
  3. 然后可以对用户设置权限以限制他们的访问权限

这意味着身份服务器就是这样,身份服务器(意味着我允许人们通过 Google 等登录,而不用担心他们的角色和权限)。

所以,为了实现上述目的,我需要检查用户对 API 的权限,而不是客户端(客户端可以是任何东西 - 网络、手机应用程序、JavaScript 客户端等,所以我们不能依赖它处理用户权限)。

在 API 上,我实现了 Permissionhandler 和 PermissionRequirement 授权策略。因此,在 API 控制器或方法上,我可以执行以下操作:[Authorize(Policy = "CreateUser")]。看来我需要为每个系统权限制定一个策略。

所以在授权处理程序中我需要:

  1. 获取当前用户的用户名
  2. 如果它们存在于应用数据库中,请检查它们的权限并进行身份验证或拒绝
  3. 如果它们在应用数据库中不存在,请添加它们,然后我们可以稍后从管理面板设置它们的权限

在我尝试从身份服务器请求用户的用户名之前,这一切进展顺利。我知道我需要使用 UserInfoClient 来执行此操作,但我不知道如何使用用户的令牌/凭据从身份服务器获取他们的声明或至少获取他们的 User.Identity.Name。

现在我可以只使用子 ID 将用户添加到应用程序数据库,但是管理权限的人将不知道那个人是谁,所以我需要使用他们的电子邮件。

现在在 MVC 客户端中,我可以毫无问题地看到 User.Identity.Name,但在 API 中该值为 null!?

所以我的问题是:到底如何从 API 中获取当前用户的 Identity.Name、用户名或电子邮件?

谢谢。

【问题讨论】:

    标签: c# asp.net-mvc api permissions identityserver4


    【解决方案1】:

    我相信您已经在 Web API 中配置了 IdentityServerAuthentication,类似于 this -

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
       ...
       app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
       {
          Authority = "http://UrlOfIentityServer",
          RequireHttpsMetadata = false,
          ApiName = "exampleapi"
       });
       ...
    }
    

    当您进行网络服务调用时,您需要传递从 IdentityServer 收到的相同 token喜欢this -

    using (var httpClient = new HttpClient())
    {
       string accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");
    
       httpClient.BaseAddress = new Uri("http://UrlOfWebAPI");
       httpClient.DefaultRequestHeaders.Clear();
       httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    
       return await httpClient.GetStringAsync("api/clock/time");
    }
    

    【讨论】:

    • 我在我的应用程序的另一层(即另一个项目)中有我的授权处理程序,所以我无法以这种方式访问​​ HttpContext。我可以访问 AuthorizationHandlerContext,但不确定是否可以访问 HttpContext?我可能错了。
    【解决方案2】:

    我想我现在已经破解了。

                var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
            if (mvcContext != null)
            {
                // Use the UserInfo endpoint to get the user's claims
                var discoveryClient = new DiscoveryClient("http://localhost:5000");
                var doc = await discoveryClient.GetAsync();
    
                var accessToken = await mvcContext.HttpContext.Authentication.GetTokenAsync("access_token");
    
                var userInfoClient = new UserInfoClient(doc.UserInfoEndpoint);
                var response = await userInfoClient.GetAsync(accessToken);
    
                var claims = response.Claims;
            }
    

    这在https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies 的底部有详细说明,因此根据微软的说法,这是正确的方法。

    不过,您确实激发了这个想法,谢谢 Win。我盯着这该死的东西看了好几个小时。有时你只需要别人说点什么,什么,诅咒就被打破了! :)

    如果有人有的话,我仍然愿意找到更好的方法来实现这一点。

    干杯

    【讨论】:

    • 不客气。 +1,感谢您的分享,所以我也学到了一些东西。
    • 我正在寻求做类似的事情,并且非常沮丧地发现只有身份服务器提供role 声明的 RBAC 示例。这对我来说似乎也是错误的。应用程序应确定用户拥有哪些权限,并将其与客户端请求的权限进行比较。仅仅因为客户端已收到用户的同意,并不意味着用户实际上有权执行所请求的操作。我对您的方法的唯一问题是,如果用户更改他们的电子邮件地址或其他身份声明怎么办 - 这将如何在应用程序级别更新
    • @crush 这是一个很好的观点,而不是我已经弄清楚的事情(我正在从事的项目不再进行)。也许这是我们不需要担心的事情。有些人对不同的服务有不同的电子邮件,所以我们是否应该关心他们是否在 IdentityServer 上更改了他们的电子邮件?如果我们确实关心,那么我们可以设置配置文件编辑器以将相关更改传递给 IdentityServer?无论如何,这些都是我最初的想法。
    • @Craig 感谢您的回复。我的观点是身份服务器应该对资源服务器一无所知。我的意思是,它知道它们存在,但不知道它们存在于哪里或如何联系它们。我一直在与同事进行一些内部辩论,关于谁应该拥有诸如“名字、姓氏、显示名称”之类的数据,以及是否应该存在该数据的应用程序本地版本,或者是否应该始终向身份服务器询问.对于当前用户来说,很容易将其从声明中移除,但其他用户呢?如果我想出一个“好”的解决方案,我会尝试添加新评论
    • @Craig 您是否将上下文注入您的控制器?当我使用这段代码时,我的控制器不知道从什么上下文中获取 .Resource。我可以立即访问 httpContext.authentication.GetTokenAsync() 。那么上下文从何而来
    猜你喜欢
    • 2020-02-17
    • 2021-02-26
    • 2018-06-14
    • 2018-05-09
    • 1970-01-01
    • 2019-12-13
    • 2012-06-12
    • 1970-01-01
    • 2017-10-03
    相关资源
    最近更新 更多