如何在ASP.Net MVC应用程序中使用来自WCF身份validation服务的身份validationcookie

好吧,我很幸运能找到适合我特定场景的任何文档或教程。

我有一个ASP.Net MVC Web应用程序,它将使用WCF服务,包括身份validation和角色(通过WCF后端的成员资格提供程序)。

我设置身份validation服务没有问题,但它没有在Web应用程序中设置cookie。 服务的Login方法的文档表明可以连接CreatingCookie事件,但它对客户端没有任何影响(我在服务端尝试过,再次没有影响)。 所以我想出了如何捕获cookie 。 我试图在客户端上手动设置auth cookie,但到目前为止它没有工作; 由于填充而导致解密失败,并且客户端无法读取服务器给出的cookie值。

有人知道你应该如何使用WCF身份validation服务生成的cookie吗? 我是否只是假设会话全部在WCF服务器上进行管理,并且在每次加载页面时只检查服务上的IsLoggedIn()?

提前致谢。

我最近一直在尝试实现您所描述的相同function。 我已设法使用以下代码:

private readonly AuthenticationServiceClient service = new AuthenticationServiceClient(); public void SignIn(string userName, string password, bool createPersistentCookie) { using (new OperationContextScope(service.InnerChannel)) { // login service.Login(userName, password, String.Empty, createPersistentCookie); // Get the response header var responseMessageProperty = (HttpResponseMessageProperty) OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name]; string encryptedCookie = responseMessageProperty.Headers.Get("Set-Cookie"); // parse header to cookie object var cookieJar = new CookieContainer(); cookieJar.SetCookies(new Uri("http://localhost:1062/"), encryptedCookie); Cookie cookie = cookieJar.GetCookies(new Uri("http://localhost:1062/"))[0]; FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value); if (null != ticket) { //string[] roles = RoleManager.GetRolesFromString(ticket.UserData); HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(ticket), null); FormsAuthentication.SetAuthCookie(HttpContext.Current.User.Identity.Name, createPersistentCookie); } } } 

它完全按照您描述的问题的评论。

编辑

我在这里发布此代码的服务器端部分以供参考。

 public class HttpResponseMessageInspector : BehaviorExtensionElement, IDispatchMessageInspector, IServiceBehavior { public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { HttpRequestMessageProperty httpRequest = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; if (httpRequest != null) { string cookie = httpRequest.Headers[HttpRequestHeader.Cookie]; if (!string.IsNullOrEmpty(cookie)) { FormsAuthentication.Decrypt(cookie); FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(cookie); string[] roles = PrincipalHelper.GetUserRoles(authTicket); var principal = new BreakpointPrincipal(new BreakpointIdentity(authTicket), roles); HttpContext.Current.User = principal; } // can deny request here } return null; } } 

这对我有用…首先设置主机的身份validation行为(这里通过代码显示,但也可以在配置中完成):

 ServiceAuthorizationBehavior author = Description.Behaviors.Find(); author.ServiceAuthorizationManager = new FormCookieServiceAuthorizationManager(); author.PrincipalPermissionMode = PrincipalPermissionMode.Custom; author.ExternalAuthorizationPolicies = new List { new CustomAuthorizationPolicy() }.AsReadOnly(); 

然后是助手类

  internal class FormCookieServiceAuthorizationManager : ServiceAuthorizationManager { public override bool CheckAccess(OperationContext operationContext) { ParseFormsCookie(operationContext.RequestContext.RequestMessage); return base.CheckAccess(operationContext); } private static void ParseFormsCookie(Message message) { HttpRequestMessageProperty httpRequest = message.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; if (httpRequest == null) return; string cookie = httpRequest.Headers[HttpRequestHeader.Cookie]; if (string.IsNullOrEmpty(cookie)) return; string regexp = Regex.Escape(FormsAuthentication.FormsCookieName) + "=(?[^;]+)"; var myMatch = Regex.Match(cookie, regexp); if (!myMatch.Success) return; string cookieVal = myMatch.Groups["val"].ToString(); FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(cookieVal); Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), new string[0]); } } internal class CustomAuthorizationPolicy : IAuthorizationPolicy { static readonly string _id = Guid.NewGuid().ToString(); public string Id { get { return _id; } } public bool Evaluate(EvaluationContext evaluationContext, ref object state) { evaluationContext.Properties["Principal"] = Thread.CurrentPrincipal; evaluationContext.Properties["Identities"] = new List { Thread.CurrentPrincipal.Identity }; return true; } public ClaimSet Issuer { get { return ClaimSet.System; } } } 

并且当设置AspNetCompatibility时, FormCookieServiceAuthorizationManager稍微简单一些:

  internal class FormCookieServiceAuthorizationManager : ServiceAuthorizationManager { public override bool CheckAccess(OperationContext operationContext) { Thread.CurrentPrincipal = HttpContext.Current.User; return base.CheckAccess(operationContext); } }