简体   繁体   English

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

[英]How to use authentication cookie from WCF Authentication Service in an ASP.Net MVC application

Okay, I've had little luck finding any documentation or tutorials for my specific scenario. 好的,我没有找到适合我特定场景的任何文档或教程。

I have an ASP.Net MVC web application that will be using WCF services for everything including authentication and roles (via membership providers on the WCF backend). 我有一个ASP.Net MVC Web应用程序,它将使用WCF服务,包括身份验证和角色(通过WCF后端的成员资格提供程序)。

I've had no problem setting up the authentication services but it does not set a cookie in the web app. 设置身份验证服务没有问题但它没有在Web应用程序中设置cookie。 The docs for the Login method of the service indicate that wiring up the CreatingCookie Event is possible, but it does not have any affect on the client (I tried on the service side as well, again no affect). 服务Login方法的文档表明可以连接CreatingCookie事件,但它对客户端没有任何影响(我在服务端尝试过,再次没有影响)。 So I figured out how to capture the cookie . 所以我想出了如何捕获cookie I have tried to manually set the auth cookie on the client, but so far it is not working; 我试图在客户端上手动设置auth cookie,但到目前为止它没有工作; decrypting fails due to padding, and setting the cookie value from the one given by the server is not readable by the client. 由于填充而导致解密失败,并且客户端无法读取服务器给出的cookie值。

Does anybody know how you are supposed to use the cookie that is generated by the WCF Authentication Service? 有人知道你应该如何使用WCF身份验证服务生成的cookie吗? Do I just assume the session is all managed on the WCF server and just check IsLoggedIn() on the service at every page load? 我是否只是假设会话全部在WCF服务器上进行管理,并在每次加载页面时检查服务上的IsLoggedIn()?

Thanks in advance. 提前致谢。

I have recently been trying to implement the same functionality you have described. 我最近一直在尝试实现您描述的相同功能。 I have managed to get it working with the following code: 我已设法使用以下代码:

    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);
            }
        }
    }

It does exactly what you have described the comment to your question. 它完全按照您描述的问题评论。

EDIT 编辑

I am posting here the Server-Side portion of this code for reference. 我在这里发布此代码的服务器端部分以供参考。

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;
    }
}

This works for me... First setup the authentication behavior of the host (here shown through code, but can also be done in config): 这对我有用...首先设置主机的身份验证行为(这里通过代码显示,但也可以在配置中完成):

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

And then the helper classes 然后是辅助类

  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) + "=(?<val>[^;]+)";
        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<IIdentity> { Thread.CurrentPrincipal.Identity };
        return true;
     }

     public ClaimSet Issuer
     {
        get { return ClaimSet.System; }
     }
  }

And for when AspNetCompatibility is set, then FormCookieServiceAuthorizationManager is slightly simpler: 并且当设置AspNetCompatibility时, FormCookieServiceAuthorizationManager稍微简单一些:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Asp.net MVC 4应用程序中使用身份验证和授权? - How to use Authentication and Authorization in Asp.net MVC 4 application? ASP.NET MVC中的身份cookie身份验证 - Identity cookie authentication in ASP.NET MVC 如何使用基本身份验证来访问从Windows服务使用Windows身份验证的Asp.Net MVC 4 Intranet Web API方法? - How to use Basic Authentication to access Asp.Net MVC 4 Intranet Web API method which uses Windows Authentication from a Windows Service? WCF服务中的ASP.NET成员身份验证 - ASP.NET Membership Authentication in WCF service 如何在ASP.net Core应用程序中同时使用Bearer和Cookie身份验证? - How can I use both Bearer and Cookie authentication in my ASP.net Core application? ASP.NET MVC 2和FormsAuthentication的Web服务身份验证 - Web-service authentication from ASP.NET MVC 2 and FormsAuthentication 如何在基于 cookie 身份验证的 asp.net mvc 项目中向 web api 添加令牌身份验证 - How to Add token authentication to web api in cookie authentication based asp.net mvc project ASP.NET身份验证Cookie - ASP.NET Authentication cookie 如何在没有身份验证机制的情况下在服务堆栈中使用asp.net mvc会话 - How to use the asp.net mvc session in service stack without authentication mechanism 如何从启用基于场的身份验证的ASP.NET应用程序或ASP.NET MVC对基于SharePoint声明的Web应用程序进行身份验证 - How to authenticate sharepoint claims based web application from farm based authentication enabled asp.net application or asp.net mvc
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM