zoukankan      html  css  js  c++  java
  • [转载]利用WCF共享ASP.NET session实现WCF服务端验证

    WCF能够共享ASP.NET的session,不同的WCF客户端代理类在采用Per Call模式下访问WCF能够访问同一个ASP.NET Session.但是WCF的Session和ASP.NET的Session是不同的。

    • WCF的Session代表着服务实例,它是被客户端代理类访问时初始化的。WCF依靠消息通道,安全回话和消息模式等来联系session的。
    • 而ASP.NET的session是类似服务端的一种存储数据的模式。它是通过客户端cookie和uri来维护session的
    1. 利用ASP.NET的session实现认证,在aspx里记录用户认证信息:  
    1 string UserId = HttpContext.Current.User.Identity.Name;
    2 int Timeout = HttpContext.Current.Session.Timeout;

      2.  如果WCF服务端能够共享Asp.NET的session,必须在WCF配置文件中进行如下设置:

    1 <serviceHostingEnvironment aspNetCompatibilityEnabled="true"  />

      3. 在服务端新建一个用户类:

     1 public static class UserHelper
    2 {
    3 public const string SessionUserKey = "Session_Current_User";
    4
    5 ///<summary>
    6 /// 取得当前用户信息
    7 ///</summary>
    8 public static UserInfo CurrentUser
    9 {
    10 get
    11 {
    12 if (!HttpContext.Current.User.Identity.IsAuthenticated)
    13 {
    14 HttpContext.Current.Response.Redirect(System.Configuration.ConfigurationManager.AppSettings["LogoutRedirectUrl"]);
    15 return null;
    16 }
    17
    18 string key = SessionUserKey;
    19 object user = null;
    20
    21 if(HttpContext.Current.Session != null)
    22 user = HttpContext.Current.Session[key];
    23
    24 if (user == null)
    25 {
    26 var info = new AdminService().GetUserById(HttpContext.Current.User.Identity.Name); // 获取用户信息
    27 HttpContext.Current.Session[key] = info;
    28 return info;
    29 }
    30 return (UserInfo)user;
    31 }
    32 set { HttpContext.Current.Session[SessionUserKey] = value; }
    33 }
    34 }

      4. 在WCF服务端可以利用共享的session来判断权限:

     1 [Serializable]
    2 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    3 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    4 public partial class AdminService : IAdminService
    5 {
    6 public AdminService()
    7 {
    8 }
    9 public string InsertAdmin(Admin admin)
    10 {
    11 int errorCount = 0;
    12 if (!UserHelper.CurrentUser == null)
    13 {
    14 CustomerFaultException exception = new CustomerFaultException
    15 {
    16 ExceptionCode = "S001",
    17 ExceptionMessage = "没有权限访问,请登录!"
    18 };
    19 throw new FaultException<CustomerFaultException>(exception);
    20 }
    21 AdminSummary adminSummary = adminDal.GetAdminSummary(admin.UserId, out errorCount);
    22 if (adminSummary == null)
    23 return adminDal.InsertAdmin(admin);
    24 else
    25 return "1001";
    26 }

      5. 在客户端获取sessionId,我们可以通过Cookie获取客户端的sessionId

      

     1 void InitialInvoke()
    2 {
    3 IHelloService proxy = factory.CreateChannel();
    4 using (new OperationContextScope((IContextChannel)proxy))
    5 {
    6 Console.WriteLine(proxy.Greet("Hello"));
    7 HttpResponseMessageProperty responseProperty = OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name]
    8 as HttpResponseMessageProperty;
    9 helper = HttpSessionCookieHelper.Create((string)responseProperty.Headers[HttpResponseHeader.SetCookie]);
    10 }
    11
    12 ((IClientChannel)proxy).Close();
    13 }

    httpSessionCookieHelper是从cookie中获取sessionId的(CookieName 是“ASP.NET_SessionId”)

     1 class HttpSessionCookieHelper
    2 {
    3 const string AspNetSessionIdCookieName = "ASP.NET_SessionId";
    4 string aspNetSessionId = string.Empty;
    5 HttpSessionCookieHelper()
    6 { }
    7
    8 public static HttpSessionCookieHelper Create(string cookieString)
    9 {
    10 HttpSessionCookieHelper helper = new HttpSessionCookieHelper();
    11 helper.ParseCookieString(cookieString);
    12 return helper;
    13 }
    14
    15 public static HttpSessionCookieHelper CreateFromSessionId(string sessionId)
    16 {
    17 HttpSessionCookieHelper helper = new HttpSessionCookieHelper();
    18 helper.aspNetSessionId = sessionId;
    19 return helper;
    20 }
    21
    22 public void AddSessionIdToRequest(HttpRequestMessageProperty requestProperty)
    23 {
    24 if (string.IsNullOrEmpty(this.aspNetSessionId))
    25 return;
    26
    27 string sessionCookieString = string.Format("{0}={1}", AspNetSessionIdCookieName, this.aspNetSessionId);
    28 string cookieString = (string)requestProperty.Headers[HttpRequestHeader.Cookie];
    29 if (string.IsNullOrEmpty(cookieString))
    30 {
    31 cookieString = sessionCookieString;
    32 }
    33 else
    34 {
    35 cookieString = string.Format("{0}; {1}", cookieString, sessionCookieString);
    36 }
    37
    38 requestProperty.Headers[HttpRequestHeader.Cookie] = cookieString;
    39 }
    40
    41 void ParseCookieString(string cookieString)
    42 {
    43 if (string.IsNullOrEmpty(cookieString))
    44 return;
    45
    46 string[] cookies = cookieString.Split(';');
    47 for (int i = 0; i < cookies.Length; i++)
    48 {
    49 string[] cookieNameValues = cookies[i].Split('=');
    50 if (cookieNameValues[0] == AspNetSessionIdCookieName)
    51 {
    52 this.aspNetSessionId = cookieNameValues[1];
    53 return;
    54 }
    55 }
    56 }
    57
    58 public string AspNetSessionId
    59 {
    60 get
    61 {
    62 return this.aspNetSessionId;
    63 }
    64 }
    65 }

    这样我们可以在第一次调用的回复中获取sessionId

     1 void Invoke2()
    2 {
    3 IHelloService proxy = factory.CreateChannel();
    4 using (new OperationContextScope((IContextChannel)proxy))
    5 {
    6 HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
    7 helper.AddSessionIdToRequest(requestProperty);
    8 OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty;
    9 Console.WriteLine(proxy.Greet("Howdy"));
    10 }
    11
    12 ((IClientChannel)proxy).Close();
    13
    14 if (Interlocked.Increment(ref completedCount) == 2)
    15 {
    16 waitHandle.Set();
    17 }
    18 }

    注:第5点可以参照:http://blogs.msdn.com/b/wenlong/archive/2010/02/21/using-asp-net-sessions-from-wcf.aspx

  • 相关阅读:
    Office365常用的命令(持续更新中)
    7:OracleRAC安装配置(19C)
    5:安装配置 Oracle18C
    课程7:邮箱的备份恢复
    课程6: powershell运维
    Exchange2013之HTTP重定向
    Powershell运维:导出Exchange系统里面所有用户的邮箱
    灾难恢复:恢复已经删除的邮箱(AD账号也被删除,14天内)
    灾难恢复:恢复丢失的exchange服务器
    2:Oracle体系结构(物理结构)
  • 原文地址:https://www.cnblogs.com/fx2008/p/2241382.html
Copyright © 2011-2022 走看看