详解ABP框架中Session功能的使用方法
如果一个应用程序需要登录,则它必须知道当前用户执行了什么操作。因此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的
目录代码:
类图:
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()); } } }