使用Cookie,授权属性,为.net Core 2.1中的应用程序创建会话

时间:2018-10-16 17:28:56

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

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

这是我到目前为止所拥有的: Startup.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?}");
        });
    }
}
}

UserController.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,并直接指向该网址:http://localhost:5036/Account/Login?ReturnUrl=%2FVehicles,而不是车辆/索引,并且不确定是否设置了cookie或用户是否可用于其他页面来显示结果。

1 个答案:

答案 0 :(得分:1)

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

要注销:

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