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.
I have resolved this problem after asking the same question.
You must either remove SWT.VIRTUAL
or update to the SVN build of SWT. I've posted a bug report on the SWT bug page.
Edit: your code snippet has a bug in it that is causing the ArrayIndexOutOfBoundsException
. You can resolve it by changing lines containing listenerSD
:
public void handleEvent(Event event) {
Collection<?> collectionW = (Collection<?>) event.widget
.getData(DATA_COLLECTION);
if (collectionW.size() > event.index) {
Object object = collectionW
.toArray(new Object[collectionW.size()])[event.index];
((TableItem) event.item).setText(0, object
.toString());
}
}
Best Answer
Using the System.Web dll isn't the same as using System.Web. None of the System.Web pipeline will run for your ASP.NET Core application so you can't do what you are trying to do.