views:

451

answers:

1

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).

I've had no problem setting up the authentication services but it does not set a cookie in the web app. 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). So I figured out how to capture the cookie. I have tried to manually set the auth cookie on the client, but so far it is not working; decrypting fails due to padding, and setting the cookie value from the one given by the server is not readable by the client.

Does anybody know how you are supposed to use the cookie that is generated by the WCF Authentication Service? Do I just assume the session is all managed on the WCF server and just check IsLoggedIn() on the service at every page load?

Thanks in advance.

+1  A: 

Tap,

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.

Karl
wow, I did miss some tricks.. Let me see how this works and I'll get back to you. No matter what I really appreciate your effort and taking an interest :)
tap
this looks good on the surface, but I am seeing the same issue I ran into: System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed.My assumption on this error is that since it is 2 different contexts (client application and service application), the decrypt/encrypt is not compatible? How did you set this up to work?Again thanks for taking an interest and the effort :)
tap
Is the Asp.net MVC and WCF Host application running on the same machine? If not you will have to set both Web.config to use the same machine key. See [http://msdn.microsoft.com/en-us/library/ms998288.aspx] In my setup, both MVC and WCF Service Host are running within Visual Studio WebServer on my local machine. So the machine key would be the same. EDIT: Also you can try adding this code to you WCF Host Global.cs file to explicitly send a cookie just to rule out more one thing: http://msdn.microsoft.com/en-us/library/bb398778%28v=VS.100%29.aspx
Karl
I do have them running on the same box right now, but I'm running off IIS7 and not cassini, so machine key should already be the same. will look into the links. thanks
tap