如何在 asp.net core 2.2 中实现 Cookie 基本身份验证和

How can i implement Cookie base authentication and jwt in asp.net core 2.2?(如何在 asp.net core 2.2 中实现 Cookie 基本身份验证和 jwt?)
本文介绍了如何在 asp.net core 2.2 中实现 Cookie 基本身份验证和 jwt?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的程序中同时使用基于 cookie 的身份验证和 jwt,使用身份验证用户通过登录和 JWT 访问 mvc 控制器来访问 WebApi 资源.

I want to use both cookie based authentication and jwt in my program, used authentication user to access mvc controller with login and JWT to access WebApi resource.

我尝试使用其中两个 首先,我的客户端可以使用用户名和密码登录并使用 cookie 进行身份验证.使用带有令牌承载的 WebApi 的应用程序的第二次访问资源,但出现错误!

I tried using two of them First, my client can login and authenticate with the cookie using username and password. Second access resource from Application with WebApi with Token Bearer but I get an error!

在我的 startup.cs 文件中,我有:

In my startup.cs file I have:

public void ConfigureServices(IServiceCollection services)
        {


            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
                options.ConsentCookie.Name = "Cookie";
            });
            services.ConfigureApplicationCookie(options =>
            {
                options.Cookie.Name = "Cookie";
                options.ClaimsIssuer = Configuration["Authentication:ClaimsIssuer"];
            });

            services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<ApplicationUser, ApplicationRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultUI(UIFramework.Bootstrap4)
                .AddDefaultTokenProviders();

            services.Configure<IdentityOptions>(options =>
            {
                // Password settings.
                options.Password.RequireDigit = true;
                options.Password.RequireLowercase = true;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                options.Password.RequiredLength = 5;
                options.Password.RequiredUniqueChars = 1;

                // Lockout settings.
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                options.Lockout.MaxFailedAccessAttempts = 5;
                options.Lockout.AllowedForNewUsers = true;

                // User settings.
                options.User.AllowedUserNameCharacters =
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
                options.User.RequireUniqueEmail = false;

                //Token
            });

            services.AddAuthentication(options =>
            {
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;

            })
                .AddCookie(options =>
                {
                    options.Cookie.Name = "Cookie";
                    options.ClaimsIssuer = Configuration["Authentication:ClaimsIssuer"];
                })
                .AddMicrosoftAccount(microsoftOptions =>
                 {
                     microsoftOptions.ClientId = Configuration["Authentication:Microsoft:ApplicationId"];
                     microsoftOptions.ClientSecret = Configuration["Authentication:Microsoft:Password"];
                 })
                .AddGoogle(googleOptions => 
                {
                    googleOptions.ClientId = "XXXXXXXXXXX.apps.googleusercontent.com";
                    googleOptions.ClientSecret = "g4GZ2#...GD5Gg1x";
                    googleOptions.Scope.Add("https://www.googleapis.com/auth/plus.login");
                    googleOptions.ClaimActions.MapJsonKey(ClaimTypes.Gender, "gender");
                    googleOptions.SaveTokens = true;
                    googleOptions.Events.OnCreatingTicket = ctx =>
                    {
                        List<AuthenticationToken> tokens = ctx.Properties.GetTokens()
                            as List<AuthenticationToken>;
                        tokens.Add(new AuthenticationToken()
                        {
                            Name = "TicketCreated",
                            Value = DateTime.UtcNow.ToString()
                        });
                        ctx.Properties.StoreTokens(tokens);
                        return Task.CompletedTask;
                    };
                })
                .AddJwtBearer(options =>
                {
                    options.ClaimsIssuer = Configuration["Authentication:ClaimsIssuer"];
                    options.SaveToken = true;
                    options.Authority = Configuration["Authentication:Authority"];
                    options.Audience = Configuration["Authentication:Audience"];
                    options.RequireHttpsMetadata = false;
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {

                        ValidateIssuerSigningKey = true,

                        ValidateIssuer = true,
                        ValidIssuer = Configuration["Authentication:ValidIssuer"],

                        ValidateAudience = true,
                        ValidAudience = Configuration["Authentication:ValidAudience"],

                        ValidateLifetime = true,

                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:SecurityKey"]))
                    };
                });






            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddSession();

            services.AddSingleton<IConfiguration>(Configuration);

        }

我在这个控制器中得到了一个令牌:

And I got a token in this controller:

[AllowAnonymous]
        [HttpPost]
        public async Task<IActionResult> GetToken(TokenLoginModel model)
        {

            if (!ModelState.IsValid) return BadRequest("Token failed to generate");
            var user = await _usermanager.FindByNameAsync(model.UserName);
            //var user = true;// (model.Password == "password" && model.Username == "username");
            if (user != null && await _usermanager.CheckPasswordAsync(user, model.Password))
            {
                var claims = new[]{
                    new Claim("ClaimsIssuer", _configuration.GetSection("Authentication:ClaimsIssuer").Value),
                new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Sub,user.UserName),
                new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString())
            };
                string SecurKey = Startup.StaticConfig.GetSection("Authentication:SecurityKey").Value;
                var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurKey));
                var token = new JwtSecurityToken(
                    issuer: _configuration.GetSection("Authentication:ValidIssuer").Value,
                    audience: _configuration.GetSection("Authentication:Audience").Value,
                    expires: DateTime.UtcNow.AddDays(30),
                    claims: claims,
                    signingCredentials: new Microsoft.IdentityModel.Tokens.SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
                );
                return Ok(new
                {
                    token = new JwtSecurityTokenHandler().WriteToken(token),
                    expiration = token.ValidTo
                });
            }
            return Unauthorized();

        }

我实现了创建令牌的控制,但是当我尝试使用它进行授权时,我得到了这个错误:

I implement control that creates token, but when I tried authorizing with that I get this error:

An unhandled exception occurred while processing the request.

HttpRequestException: Response status code does not indicate success: 404 (Not Found).
System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()

IOException: IDX20804: Unable to retrieve document from: 'https://localhost:44383/oauth2/default/.well-known/openid-configuration'.
Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(string address, CancellationToken cancel)

InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://localhost:44383/oauth2/default/.well-known/openid-configuration'.
Microsoft.IdentityModel.Protocols.ConfigurationManager<T>.GetConfigurationAsync(CancellationToken cancel)

推荐答案

为了增加对 JWT 的支持,我们添加了 AddCookie 和 AddJwtBearer.让网站需要标头中的令牌会让人头疼,尤其是对于不是纯粹的 SPA 或 API 的项目.所以我真正想要的是同时支持 Cookie 和 JWT.

In order to add support for JWT, we added the AddCookie and AddJwtBearer. Having websites require the token in the header would be a headache, especially for projects that aren’t purely SPA or API. So what I really wanted was support for both Cookies and JWTs.

在 startup.cs 你有:

In startup.cs you have:

    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)
    {
      services.AddDbContext<DualAuthContext>(options =>
          options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

      services.AddIdentity<ApplicationUser, IdentityRole>()
          .AddEntityFrameworkStores<DualAuthContext>()
          .AddDefaultTokenProviders();

      // Enable Dual Authentication 
      services.AddAuthentication()
        .AddCookie(cfg => cfg.SlidingExpiration = true)
        .AddJwtBearer(cfg =>
        {
          cfg.RequireHttpsMetadata = false;
          cfg.SaveToken = true;
          cfg.TokenValidationParameters = new TokenValidationParameters()
          {
            ValidIssuer = Configuration["Tokens:Issuer"],
            ValidAudience = Configuration["Tokens:Issuer"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
          };
        });

      // Add application services.
      services.AddTransient<IEmailSender, EmailSender>();
      services.AddMvc();
    }

在配置方法中:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, DataSeeder seeder)
{
  ...
  app.UseAuthentication();
}

在您的控制器中使用 JWT 之后,您应该将 JWT Bearer AuthenticationSchemes 添加到 Authorize 属性,如下所示:

After this in your controller that one you have used JWT, You should add JWT Bearer AuthenticationSchemes to Authorize attribute like this :

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
  [Route("/api/customers")]
  public class ProtectedController : Controller
  {
    public ProtectedController()
    {
    }

    public IActionResult Get()
    {
      return Ok(new[] { "One", "Two", "Three" });
    }
  }

参考:ASP.NET 中的两个 AuthorizationSchemes核心2

使用起来非常简单实用.

It's very simple and helpful to used.

这篇关于如何在 asp.net core 2.2 中实现 Cookie 基本身份验证和 jwt?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)