网络编程
位置:首页>> 网络编程>> ASP.NET>> 详解ABP框架中Session功能的使用方法

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

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

标签: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());
   }
 }
}

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com