简体   繁体   中英

Use cookie, authorize attribute, create session for application in .net core 2.1

I'm unfamiliar with .net core 2.1 authorization, authentication and cookies.I am trying to implement a web application that 1. sends an email to a user with a token. 2. user clicks on link provided in email to login to application 3. We create a cookie/session for the user that is only valid as long as browser window is open. 3. The authorize attribute must be used on controller actions and the logged in user must be available for linking pages together 4. Display logged in username on mvc view

Here is what i have so far: 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());
    }

I get a 404 and am directed to this url: http://localhost:5036/Account/Login?ReturnUrl=%2FVehicles instead of vehicles/index and also am not sure if cookie is set or user is available for other pages to display results.

You need to add services.AddAuthorization(); below services.AddAuthentication(...) and on Configure app.UseAuthentication();

To log out:

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

You can get the user details like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM