I've been hitting this one for hours and I'm stumped. I'm making an ajax post request to an MVC 5 controller in an attempt to auto-login a specific pre-defined "super" user. In the controller method, I'm trying to programmatically set the HttpContext.Current.User and authenticate, so the super user can skip the process of manually logging in. The consensus on this seems to be here, which I implemented:
setting HttpContext.Current.User
This seems to work until I try to view any other controller methods with a custom AuthorizeAttribute.
Controller method:
[HttpPost]
[AllowAnonymous]
public ActionResult Login(string username)
{
string password = ConfigurationManager.AppSettings["Pass"];
User user = service.Login(username, password);
var name = FormsAuthentication.FormsCookieName;
var cookie = Response.Cookies[name];
if (cookie != null)
{
var ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket != null && !ticket.Expired)
{
string[] roles = (ticket.UserData as string ?? "").Split(',');
System.Web.HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(ticket), roles);
}
}
//...processing result
return Json(result);
}
The service.Login method above creates the cookie:
FormsAuthentication.SetAuthCookie(cookieValue, false);
Though I'm setting the User, which has an Identity and IsAuthenticated is true, the filterContext.HttpContext.User below is not the same user. It's essentially empty as if it was never assigned, and is not authenticated.
public override void OnAuthorization(AuthorizationContext filterContext)
{
string[] userDetails = filterContext.HttpContext.User.Identity.Name.Split(char.Parse("|"));
}
The closest post I could find is here: IsAuthenticated works on browser - but not with Air client!
However, the fix for that was already in place for me:
<authentication mode="Forms">
<forms cookieless="UseCookies" timeout="60" loginUrl="~/Account/Login" />
</authentication>
What am I missing to make the AuthorizationContext.User match the HttpContext.Current.User that I'm authenticating in the controller?
UPDATE:
I realize I need a redirect to set the cookie properly, I'm just not able to make that work remotely, via an ajax call. Here's what the script in site A looks like, when executing the controller method on site B. This redirect doesn't set the session. It still isn't present when authenticating the user on the next controller method. It just redirects me back to the login view.
function remoteLogin(id) {
$.ajax({
url: "/MyController/RemoteLogin",
type: "POST",
dataType: "json",
data: { "id": id }
}).done(function (data) {
if (data) {
if (data.user) {
var user = data.user;
$.ajax({
url: "http://siteB.xyz/Account/Login",
type: "POST",
dataType: "json",
data: { "username": user.username, "password": user.password }
}).done(function (data) {
if (data) {
window.location.href = "http://siteB.xyz/Next"
} else {
alert("Fail.");
}
}).fail(function (data) {
alert("Fail.");
});
} else {
alert("Fail.");
}
}
}).fail(function (data) {
alert("Fail.");
});
}