【问题标题】:Provide token with identity server 4 only if the user fulfills certain conditions仅当用户满足某些条件时才向身份服务器 4 提供令牌
【发布时间】:2018-11-29 05:53:26
【问题描述】:

我重新搜索了大约一周,但没有找到任何解决问题的方法。

我在 .NET Core 2 Api 和身份服务器 4 上使用 ASP.NET Core 身份验证来自 Angular 4 客户端应用程序的用户。

我的问题是: 只有当用户满足数据库中的某些值时(例如,EmailConfirmed 为 1(真)等等),是否有任何解决方案可以从 /connect/token 端点向用户提供令牌。

如果我不够清楚,请在下面发表评论。

【问题讨论】:

  • 另外,我可以在身份服务器级别进行 SQL 查询吗?

标签: asp.net-core identityserver4


【解决方案1】:

您可以使用IProfileService 作为扩展点。

IdentityServer4.AspNetIdentity 包已经提供了一个ProfileService<TUser>(参见source)类,该类可以扩展为所需的行为。

在那里你可以覆盖IsActiveAsync 方法并添加你想要的逻辑。

public class ConfirmedUsersProfileService : ProfileService<TUser>
{
    public override async Task IsActiveAsync(IsActiveContext context)
    {
        var sub = context.Subject.GetSubjectId();
        var user = await _userManager.FindByIdAsync(sub);
        context.IsActive = user != null && user.EmailConfirmed == true;
    }
}

当用户在数据库中不存在或他的电子邮件未被确认时,他将不会登录,因此不会返回任何令牌。

这在官方Identity4 Docs中也有明确描述。

IsActiveAsync

预计当前是否允许用户获取令牌的 API。它传递了一个IsActiveContext 的实例。

然后注册新的ConfirmedUsersProfileService而不是旧的服务:

services.AddIdentityServer()
    ...
    .AddProfileService<ConfirmedUsersProfileService>();

另外,我可以在身份服务器级别进行 SQL 查询吗?

是的,您可以将任何服务注入ConfirmedUsersProfileService,即IdentityDbContext&lt;TUser&gt;UserManager&lt;TUser&gt;(已经注入,您只需在派生类中保留对它的引用,就像ProfileService&lt;TUser&gt; 被标记为私有。)然后对其执行任何查询。

P.S. IProfileService 可以也应该用作令牌扩展点。此时您也可以从令牌中添加其他(或删除现有)声明。

【讨论】:

  • 感谢您的回答,但同时我设法覆盖了 IResourceOwnerPasswordValidator 接口,并在那里执行了逻辑。现在我的愿望是在生成令牌时添加一些声明。我这样添加: var claim = new List { new Claim(ClaimTypes.MobilePhone, user.PhoneNumber), }; context.Result = new GrantValidationResult(user.UserName, "password", claim);.当我在控制器中时,我在 HTTPContext.User 中看不到任何声明,你知道为什么吗?
  • 您无法在控制器中添加声明,当您点击控制器时,声明主体和令牌已经创建。当身份服务器请求令牌时,您应该使用上面的IProfileService 添加令牌。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-13
相关资源
最近更新 更多