定制用户身份

默认情况下,ClownFish会在请求进入时识别用户身份,并构造相关一系列身份对象。

对于开发者来说,只需要一个调用就可以获取到用户身份信息:

// 下面代码可在 Controller 代码中使用
IUserInfo userinfo = this.NHttpContext.GetUserInfo();

再或者可以使用下面方式来做授权检查

[Authorize(Roles = "Admin,AppClient")]



在这些代码的背后,ClownFish需要做2件事情:

  • 识别用户身份并构造LoginTicket对象,默认来源有2个(名称可配置):请求头 或者 Cookie
  • 根据LoginTicket对象设置 httpContext.User 属性

默认情况下,httpContext.User 属性的值是一个 NbPrincipal 对象。



数据来源扩展

如果你需要使用其它的身份标识来源,例如:

  • 从 Redis 中加载已登录的用户身份 (其实是一种Session实现方式)
  • 从其它格式的Cookie或者Header中加载用户身份

那么可以参考下面示例。

public sealed class DemoAuthenticateModule : NHttpModule
{
    public override void AuthenticateRequest(NHttpContext httpContext)
    {
        // 从其它来源获取用户身份
        IUserInfo userinfo = GetUserInfo(...);

        // 构造登录身份凭证对象
        LoginTicket ticket = new LoginTicket{ User = userinfo };

        // 设置 httpContext.User
        httpContext.User = new NbPrincipal(ticket, LoginTicketSource.Others);
    }
}



身份类型扩展

ClownFish在内部会使用 NbPrincipal和 NbIdentity 来封装用户身份相关数据。

如果你需要在请求中维护更多信息,也可以自行实现下面2个接口:

  • IPrincipal,这个接口是 httpContext.User 的类型要求
  • INbIdentity,这个接口是包含用户身份的数据对象

示例代码

public sealed class MyIdentity : ClaimsIdentity, INbIdentity
{
     public IUserInfo UserInfo { get; }

     public Xxxxx OtherData { get; }  // 其它身份数据

     // 这里省略构造方法相关代码
}

public sealed class MyPrincipal : ClaimsPrincipal
{
    // 省略数据成员定义相关代码

    public MyPrincipal(LoginTicket ticket)
    {
        this.AddIdentity(new MyIdentity(ticket.User, ....otherData));
    }
}


public sealed class MyAuthenticateModule : NHttpModule
{
    public override void AuthenticateRequest(NHttpContext httpContext)
    {
        // 从其它来源获取用户身份
        IUserInfo userinfo = GetUserInfo(...);

        // 构造登录身份凭证对象
        LoginTicket ticket = new LoginTicket{ User = userinfo, ....};

        // 设置 httpContext.User
        httpContext.User = new MyPrincipal(ticket);        
    }
}