【问题标题】:Use cookie, authorize attribute, create session for application in .net core 2.1在 .net core 2.1 中使用 cookie、授权属性、为应用程序创建会话
【发布时间】:2018-10-16 17:28:55
【问题描述】:

我不熟悉 .net core 2.1 授权、身份验证和 cookie。我正在尝试实现一个 Web 应用程序 1. 使用令牌向用户发送电子邮件。 2. 用户点击电子邮件中提供的链接登录应用程序 3. 我们为用户创建一个只有在浏览器窗口打开时才有效的 cookie/会话。 3. authorize 属性必须用于控制器操作,并且登录用户必须可用于将页面链接在一起 4.在mvc视图上显示登录用户名

这是我目前所拥有的: 启动.cs

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using VVF_Entity.Models;
using Prototype.Services;
using System;

namespace Prototype
{
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        var AppSettingsSection = Configuration.GetSection("AppSettings");

        services.AddHttpContextAccessor();

        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddDistributedMemoryCache();
        services.AddSession(options =>
        {
            // Set a short timeout for easy testing.
            options.IdleTimeout = TimeSpan.FromSeconds(10);
            options.Cookie.HttpOnly = true;
        });

        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie();
                //.AddCookie(options =>
                //{
                //    options.LoginPath = "/User/Login/";
                //});

        services.AddMvc();

        services.AddSingleton<IEmailSender, AuthMessageSender>();
        services.AddDbContext<VVFContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}
}

用户控制器.cs

    public async Task<ActionResult> Login(Guid authcode)
    {
        if (authcode == null)
        {

            return NotFound();
        }

        var submitter = await _context.Submitters
            .FirstOrDefaultAsync(m => m.Token == authcode);
        if (submitter == null)
        {
            return NotFound();
        }
        else
        {
            if(submitter.ModifiedDate > DateTime.Now.AddHours(-1))
            { 
                submitter.EmailConfirmed = true;
                _context.Update(submitter);
                await _context.SaveChangesAsync();

                var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, submitter.FirstName)
                };
                ClaimsIdentity userIdentity = new ClaimsIdentity(claims, "login");
                ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);

                await HttpContext.SignInAsync(principal);
                //return View(submitter);
                return RedirectToAction("Index", "Vehicles");
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }                
        }         
    }

VehiclesController.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using VVF_Entity.Models;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace VVF_Web.Controllers
{
    [Authorize]
    public class VehiclesController : Controller
{
    private readonly VVFContext _context;

    public VehiclesController(VVFContext context)
    {
        _context = context;
    }

    // GET: Vehicles
    public async Task<IActionResult> Index()
    {
        // TO DO: Where SubmitterId = Authenticated Submitter
        var VVFContext = _context.Vehicles.Include(v => v.ExemptReason).Include(v => v.Submitter);


        return View(await VVFContext.ToListAsync());
    }

我收到 404 并被定向到此 url:http://localhost:5036/Account/Login?ReturnUrl=%2FVehicles 而不是车辆/索引,并且我不确定是否设置了 cookie 或用户是否可用于其他页面显示结果。

【问题讨论】:

  • 太棒了。那行得通。您能告诉我如何验证会话 cookie 是否已创建吗?另外,我如何使 cookie 无效,在视图中显示用户名和用户详细信息?并为页面之间的后续请求使用相同的用户?

标签: c# asp.net-core-2.1


【解决方案1】:

您需要在services.AddAuthentication(...) 下方和配置app.UseAuthentication(); 上添加services.AddAuthorization();

退出:

public async Task Logout()
{
   await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}

您可以像这样获取用户详细信息:

public class YourControllerNameController : Controller
{
   public IActionResult YourMethodName()
   {
       var userId =  User.FindFirst(ClaimTypes.NameIdentifier).Value // will give the user's userId
       var userName =  User.FindFirst(ClaimTypes.Name).Value // will give the user's userName
       var userEmail =  User.FindFirst(ClaimTypes.Email).Value // will give the user's Email
   }
}

【讨论】:

  • 感谢大卫。在 view.cshtml 中有这个是个好习惯吗? @using System.Security.Claims 然后访问这些属性?
  • 我相信是这样,我可能是错的,但我还没有找到更优雅的方法来做到这一点。
  • 我不确定我是否正在使用 cookie 或会话。因为我两者都有。会话,会话cookie,cookie认证,在startup.cs中。这只是一个会话 cookie 还是我以不同的方式创建它们?
  • 我不确定,但我相信您在启动时不需要会话部分。在我所有具有身份的应用程序中,无论如何我都没有使用过会话。
猜你喜欢
  • 2020-01-30
  • 2020-07-21
  • 2021-10-23
  • 2020-10-27
  • 1970-01-01
  • 2017-09-16
  • 2020-07-21
  • 1970-01-01
  • 2021-04-29
相关资源
最近更新 更多