欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解ABP框架中Session功能的使用方法

程序员文章站 2023-12-05 21:09:22
如果一个应用程序需要登录,则它必须知道当前用户执行了什么操作。因此asp.net在展示层提供了一套自己的session会话对象,而abp则提供了一个可以在任何地方 获取...

如果一个应用程序需要登录,则它必须知道当前用户执行了什么操作。因此asp.net在展示层提供了一套自己的session会话对象,而abp则提供了一个可以在任何地方
获取当前用户和租户的iabpsession接口。

关于iabpsession
需要获取会话信息则必须实现iabpsession接口。虽然你可以用自己的方式去实现它(iabpsession),但是它在module-zero项目中已经有了完整的实现。

注入session
iabpsession通常是以属性注入的方式存在于需要它的类中,不需要获取会话信息的类中则不需要它。如果我们使用属性注入方式,我们可以用
nullabpsession.instance作为默认值来初始化它(iabpsession),如下所示:

public class myclass : itransientdependency
{
  public iabpsession abpsession { get; set; }

  public myclass()
  {
    abpsession = nullabpsession.instance;
  }

  public void mymethod()
  {
    var currentuserid = abpsession.userid;
    //...
  }
}

由于授权是应用层的任务,因此我们应该在应用层和应用层的上一层使用iabpsession(我们不在领域层使用iabpsession是很正常的)。
applicationservice, abpcontroller 和 abpapicontroller 这3个基类已经注入了abpsession属性,因此在application service的实例方法中,能直接使用abpsession属性。

使用session属性
abpsession定义的一些关键属性:

  • userid: 当前用户的标识id,如果没有当前用户则为null.如果需要授权访问则它不可能为空。
  • tenantid: 当前租户的标识id,如果没有当前租户则为null。
  • multitenancyside: 可能是host或tenant。

userid和tenantid是可以为null的。当然也提供了不为空时获取数据的 getuserid()和gettenantid() 方法 。当你确定有当前用户时,你可以使用getuserid()方法。

如果当前用户为空,使用该方法则会抛出一个异常。gettenantid()的使用方式和getuserid()类似。

abp如何实现session的
目录代码:

详解ABP框架中Session功能的使用方法

类图:

详解ABP框架中Session功能的使用方法

iabpsession:iabpsession接口

using abp.multitenancy;

namespace abp.runtime.session
{
  public interface iabpsession
  {
    long? userid { get; }
    int? tenantid { get; }
    multitenancysides multitenancyside { get; }
    long? impersonatoruserid { get; }
    int? impersonatortenantid { get; }
  }
}

nullabpsession:实现了空对象模式

using abp.multitenancy;

namespace abp.runtime.session
{
  /// <summary>
  /// implements null object pattern for <see cref="iabpsession"/>.
  /// </summary>
  public class nullabpsession : iabpsession
  {
    /// <summary>
    /// singleton instance.
    /// </summary>
    public static nullabpsession instance { get { return singletoninstance; } }
    private static readonly nullabpsession singletoninstance = new nullabpsession();

    /// <inheritdoc/>
    public long? userid { get { return null; } }

    /// <inheritdoc/>
    public int? tenantid { get { return null; } }

    public multitenancysides multitenancyside { get { return multitenancysides.tenant; } }
    
    public long? impersonatoruserid { get { return null; } }
    
    public int? impersonatortenantid { get { return null; } }

    private nullabpsession()
    {

    }
  }
}

claimsabpsession:获取会话状态

using system;
using system.linq;
using system.security.claims;
using system.threading;
using abp.configuration.startup;
using abp.multitenancy;
using abp.runtime.security;

namespace abp.runtime.session
{
  /// <summary>
  /// implements <see cref="iabpsession"/> to get session properties from claims of <see cref="thread.currentprincipal"/>.
  /// </summary>
  public class claimsabpsession : iabpsession
  {
    private const int defaulttenantid = 1;

    public virtual long? userid
    {
      get
      {
        var claimsprincipal = thread.currentprincipal as claimsprincipal;
        if (claimsprincipal == null)
        {
          return null;
        }

        var claimsidentity = claimsprincipal.identity as claimsidentity;
        if (claimsidentity == null)
        {
          return null;
        }

        var useridclaim = claimsidentity.claims.firstordefault(c => c.type == claimtypes.nameidentifier);
        if (useridclaim == null || string.isnullorempty(useridclaim.value))
        {
          return null;
        }

        long userid;
        if (!long.tryparse(useridclaim.value, out userid))
        {
          return null;
        }

        return userid;
      }
    }

    public virtual int? tenantid
    {
      get
      {
        if (!_multitenancy.isenabled)
        {
          return defaulttenantid;
        }

        var claimsprincipal = thread.currentprincipal as claimsprincipal;
        if (claimsprincipal == null)
        {
          return null;
        }

        var tenantidclaim = claimsprincipal.claims.firstordefault(c => c.type == abpclaimtypes.tenantid);
        if (tenantidclaim == null || string.isnullorempty(tenantidclaim.value))
        {
          return null;
        }

        return convert.toint32(tenantidclaim.value);
      }
    }

    public virtual multitenancysides multitenancyside
    {
      get
      {
        return _multitenancy.isenabled && !tenantid.hasvalue
          ? multitenancysides.host
          : multitenancysides.tenant;
      }
    }

    public virtual long? impersonatoruserid
    {
      get
      {
        var claimsprincipal = thread.currentprincipal as claimsprincipal;
        if (claimsprincipal == null)
        {
          return null;
        }

        var impersonatoruseridclaim = claimsprincipal.claims.firstordefault(c => c.type == abpclaimtypes.impersonatoruserid);
        if (impersonatoruseridclaim == null || string.isnullorempty(impersonatoruseridclaim.value))
        {
          return null;
        }

        return convert.toint64(impersonatoruseridclaim.value);
      }
    }

    public virtual int? impersonatortenantid
    {
      get
      {
        if (!_multitenancy.isenabled)
        {
          return defaulttenantid;
        }

        var claimsprincipal = thread.currentprincipal as claimsprincipal;
        if (claimsprincipal == null)
        {
          return null;
        }

        var impersonatortenantidclaim = claimsprincipal.claims.firstordefault(c => c.type == abpclaimtypes.impersonatortenantid);
        if (impersonatortenantidclaim == null || string.isnullorempty(impersonatortenantidclaim.value))
        {
          return null;
        }

        return convert.toint32(impersonatortenantidclaim.value);
      }
    }

    private readonly imultitenancyconfig _multitenancy;

    /// <summary>
    /// constructor.
    /// </summary>
    public claimsabpsession(imultitenancyconfig multitenancy)
    {
      _multitenancy = multitenancy;
    }
  }
}

abpsessionextensions:iabpsession扩展方法

using system;

namespace abp.runtime.session
{
  /// <summary>
  /// extension methods for <see cref="iabpsession"/>.
  /// </summary>
  public static class abpsessionextensions
  {
    /// <summary>
    /// gets current user's id.
    /// throws <see cref="abpexception"/> if <see cref="iabpsession.userid"/> is null.
    /// </summary>
    /// <param name="session">session object.</param>
    /// <returns>current user's id.</returns>
    public static long getuserid(this iabpsession session)
    {
      if (!session.userid.hasvalue)
      {
        throw new abpexception("session.userid is null! probably, user is not logged in.");
      }

      return session.userid.value;
    }

    /// <summary>
    /// gets current tenant's id.
    /// throws <see cref="abpexception"/> if <see cref="iabpsession.tenantid"/> is null.
    /// </summary>
    /// <param name="session">session object.</param>
    /// <returns>current tenant's id.</returns>
    /// <exception cref="abpexception"></exception>
    public static int gettenantid(this iabpsession session)
    {
      if (!session.tenantid.hasvalue)
      {
        throw new abpexception("session.tenantid is null! possible problems: no user logged in or current logged in user in a host user (tenantid is always null for host users).");
      }

      return session.tenantid.value;
    }

    /// <summary>
    /// creates <see cref="useridentifier"/> from given session.
    /// returns null if <see cref="iabpsession.userid"/> is null.
    /// </summary>
    /// <param name="session">the session.</param>
    public static useridentifier touseridentifier(this iabpsession session)
    {
      return session.userid == null
        ? null
        : new useridentifier(session.tenantid, session.getuserid());
    }
  }
}

相关标签: ABP