5

我已经在不同站点之间使用了表单身份验证,甚至在不同版本的 .NET 之间,但现在我们正在考虑在ASP.NET 5 (MVC 6) ASP.NET Core 中启动一个新项目,并希望使用基于 cookie跨两者形成身份验证。登录是在“旧”MVC 5 应用程序中完成的。

当前版本的 ASP.NET 5 是否可能或支持基于 cookie 的表单身份验证的某些跨应用程序配置?这可以使用FormsAuthenticationModule在MVC6 ASP.NET Core 端实现,还是可以与新的身份验证中间件一起使用?还有其他建议吗?

4

3 回答 3

2

在过去的几天里,我一直在为同样的问题苦苦挣扎……但我已经解决了……(它似乎坚持了下来)

这是为了将 windows 和以后的表单身份验证转换为 MVC5 和 MVC6 的表单身份验证,因此希望您可以更改足够的代码以使其适合您...我计划在重新编写登录脚本时更改一些部分。(这是 Alpha 版,所以会做出一些改变!)

我将以下代码放在我们的 MVC5 Intranet 站点中以获取 Windows 身份验证的角色

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");
    }

这将以表单和 MVC6 方法创建到 Windows 身份验证票证。

MVC6 的字符串看起来像“John.Doe;Windows;Admin”

然后在 MVC6 启动文件中,我将以下代码放入配置部分...

        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);
            }
        });

然后,这将获取 cookie 并从中创建一个新的声明身份。我刚刚完成了让它工作的逻辑,所以我相信它可以被整理...只是想我会把它给你,这样你就可以看看你是否能得到一些想法。

于 2015-06-22T16:18:28.790 回答
0

WebForms 不是 ASP.NET 5 的一部分。根据这篇博文,这是更改 #2

更新

ASP.NET MVC 6 的新生命周期使用中间件来组合服务。您可以使用Security包进行身份验证,但不再支持旧的“表单”身份验证。

于 2015-06-19T17:57:26.283 回答
0

这是我在 Asp.net core mvc 中的简单代码,希望对您有所帮助:

Startup.cs In Function之后ConfigureServices添加services.AddAuthorization();service.AddMvc()

在函数中Configure添加这样的代码

app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationScheme = "UserLoginCookie",
                LoginPath = new PathString("/Account/Login"),
                AccessDeniedPath = new PathString("/Account/Forbidden"),
                AutomaticAuthenticate = true,
                AutomaticChallenge = true
            }); 

app.UseMvc....

在登录方法:核心代码如下:

     var claims = new List<Claim>()
        {
            new Claim(ClaimTypes.Name,userName here),
            new Claim("UserCodeInMyWebApp",Anything you want),
            new Claim(ClaimTypes.Role,"Admin")

        };
            var userPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, "UserLoginClaimsIdentity"));
            //signin
            await HttpContext.Authentication.SignInAsync("UserLoginCookie", userPrincipal, new AuthenticationProperties
            {
                ExpiresUtc = DateTime.UtcNow.AddMinutes(20),
                IsPersistent = false,
                AllowRefresh = false
            });

            return RedirectToAction("AuthPage", "Home"); 

然后您可以通过键值访问声明值或检查是否经过身份验证:

bool flag = User.Identity.IsAuthenticated
 ClaimsIdentity user = User.Identity as ClaimsIdentity
 user.Name or user.FindFirst(the key value string you created).Value 

并像这样检查:

  [HttpGet]
        [AllowAnonymous]
        public IActionResult Index()
        {
            return View();
        }

        [Authorize(Roles = "Admin")]
        [HttpGet]
        public IActionResult AuthPage()
        {
            return View();
        }

        public IActionResult About()
        {
            return View();
        }
于 2017-01-14T08:33:06.237 回答