I have been beating my head over this same problem for the last few days... but I have solved it... (it seems to be holding up)
This is for converting windows and later forms Authentication to forms Authentication for MVC5 and MVC6 so hopefully you can change enough code to make it work for you... I plan to change some parts when I re-write the login scripts. (and this is alpha so will be making some changes!)
I put the following code in our MVC5 Intranet Site to grab the Roles for windows Authentication
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
// Get current windows Identity to get the roles out of it
WindowsIdentity ident = WindowsIdentity.GetCurrent();
string[] roles = new string[ident.Groups.Count];
int i = 0;
// get the groups from the current Identity
foreach (var g in ident.Groups)
{
roles[i] = g.Translate(typeof(System.Security.Principal.NTAccount)).Value.ToString();
i++;
}
// join into a single string the roles that the user is a member of
string roleData = String.Join(";", roles) ;
// create the forms ticket that all MVC5 sites with the same machine key will pick up.
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, ident.Name, DateTime.Now, DateTime.Now.AddMinutes(30), false, roleData, "/");
string encTicket = FormsAuthentication.Encrypt(ticket);
// add the user name first from the Principle and add Windows as this will come from Windows Auth
roleData = ident.Name + ";" + "Windows;" + roleData;
//use machine key to encrypt the data
var encTicket2 = MachineKey.Protect(System.Text.Encoding.UTF8.GetBytes(roleData),
"Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware",
"ApplicationCookie", "v1");
//create a new cookie with a base64string of the encrypted bytes
HttpCookie hc2 = new HttpCookie("cookie1", Convert.ToBase64String(encTicket2));
hc2.Domain = ".domain.com";
hc2.Expires = DateTime.Now.AddHours(8);
Response.Cookies.Add(hc2);
// NOTE: The name of the HttpCookie must match what the FormsAuth site expects.
HttpCookie hc = new HttpCookie("cookie2", encTicket);
hc.Domain = ".domain.com";
hc.Expires = DateTime.Now.AddHours(8);
Response.Cookies.Add(hc);
// Ticket and cookie issued, now go to the FormsAuth site and all should be well.
Response.Redirect("http://www.yoursite.com");
}
this will create to a windows Authentication Ticket in both the forms and MVC6 method.
The string for MVC6 will look something like "John.Doe;Windows;Admin"
Then in the MVC6 startup file I have put the following code into the configure section...
app.Use(async (context, next) =>
{
Logger _logger = new Logger("C:\\\\Logs\\Log.txt");
try
{
var request = context.Request;
var cookie = request.Cookies.Get("cookie1");
var ticket = cookie.ToString();
ticket = ticket.Replace(" ", "+");
var padding = 3 - ((ticket.Length + 3)%4);
if (padding != 0)
ticket = ticket + new string('=', padding);
var bytes = Convert.FromBase64String(ticket);
bytes = System.Web.Security.MachineKey.Unprotect(bytes,
"Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware",
"ApplicationCookie", "v1");
string ticketstring = System.Text.Encoding.UTF8.GetString(bytes);
var ticketSplit = ticketstring.Split(';');
var claims = new Claim[ticketSplit.Length];
var OriginalIssuer = "";
for (int index = 0; index != ticketSplit.Length; ++index)
{
if (index == 0)
{
claims[index] = new Claim(ClaimTypes.Name, ticketSplit[index], "Windows");
}
else if (index == 1)
{
OriginalIssuer = ticketSplit[1];
}
else
{
claims[index] = new Claim(ClaimTypes.Role,ticketSplit[0], OriginalIssuer);
}
}
var identity = new ClaimsIdentity(claims, OriginalIssuer, ClaimTypes.Name,ClaimTypes.Role);
var principal = new ClaimsPrincipal(identity);
_logger.Write(principal.Identity.Name);
context.User = principal;
_logger.Write("Cookie End");
await next();
} catch (Exception ex)
{
_logger.Write(ex.Message);
_logger.Write(ex.StackTrace);
}
});
This then takes the cookie and creates a new claims identity from it. I've only just finished the logic to get it working so I'm sure it can be tidied up... Just thought I would get it to you so you can see if you can get some ideas about it.