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 ev
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:
internal class FormCookieServiceAuthorizationManager : ServiceAuthorizationManager
{
public override bool CheckAccess(OperationContext operationContext)
{
Thread.CurrentPrincipal = HttpContext.Current.User;
return base.CheckAccess(operationContext);
}
}