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

作者:Joye.Net 时间:2024-05-13 09:16:28 

如果一个应用程序需要登录,则它必须知道当前用户执行了什么操作。因此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
0
投稿

猜你喜欢

  • php环境下利用session防止页面重复刷新的具体实现

    2023-11-14 08:51:45
  • Python实现读取TXT文件数据并存进内置数据库SQLite3的方法

    2021-03-01 14:14:27
  • asp.net php asp jsp 301重定向的代码(集合)

    2023-11-14 15:02:06
  • 在 Python 中使用 MQTT的方法

    2022-01-26 12:32:48
  • go语言中排序sort的使用方法示例

    2023-09-01 00:07:22
  • python编程webpy框架模板之def with学习

    2023-08-07 11:23:32
  • pyqt5 实现 下拉菜单 + 打开文件的示例代码

    2023-12-17 09:20:28
  • 深入理解Python内置函数map filter reduce及与列表推导式对比

    2022-06-30 21:39:11
  • tensorflow中的数据类型dtype用法说明

    2023-08-28 05:44:30
  • 白鸦:贪守米缸者,饿死灶台

    2009-02-23 13:03:00
  • 浅谈五大Python Web框架

    2023-12-10 07:33:25
  • PL/SQL 类型格式转换

    2009-02-26 11:07:00
  • Vue用v-for给循环标签自身属性添加属性值的方法

    2024-04-10 10:30:56
  • ASP MSSQL存储过程的实现小例

    2011-04-06 11:02:00
  • MySQL中where 1=1方法的使用及改进

    2024-01-17 22:00:59
  • MySQL数据库中设列的默认值为Now()的介绍

    2009-03-06 17:40:00
  • 解决MySQL Varchar 类型尾部空格的问题

    2024-01-25 15:31:28
  • 关于SSD目标检测模型的人脸口罩识别

    2023-06-20 05:20:56
  • 解决Jupyter Notebook开始菜单栏Anaconda下消失的问题

    2021-04-09 18:33:05
  • thinkPHP删除前弹出确认框的简单实现方法

    2024-06-07 15:28:58
  • asp之家 网络编程 m.aspxhome.com