使用JWT Token-在.NET Core 2.0中进行身份验证的AuthorizeAttribute

使用JWT Token-在.NET Core 2.0中进行身份验证的AuthorizeAttribute

问题描述:

我在使用.net core 2.0运行的Web-API中实现了JWT承载令牌 - 身份验证。 现在我创建了另一个与我的Web-API对话的网站。检索令牌的作品,我将它添加到cookie中,当我调试时,我可以看到我的cookie(名称是“身份”)与正确的值。使用JWT Token-在.NET Core 2.0中进行身份验证的AuthorizeAttribute

在项目模板中有控制器HomeController的操作。我使用的是行动Contact我的目的,并用其标注的AuthorizeAttribute

[Authorize] 
public IActionResult Contact() 
{ 
    ViewData["Message"] = "Your contact page."; 

    return View(); 
} 

现在,我的导航(如匿名用户)/home/contact - 完美:它重定向我/home/login,我需要登录。

当我试图登录我获得以下错误消息:

没有IAuthenticationSignInHandler被配置为处理登陆的方案:

我猜承载令牌配置有误 - 我想这里有更多的事情我做错了。

首先,这里是我的Startup.cs(我没有删除任何东西,因为有数量级的依赖):

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddDistributedMemoryCache(); 

    services.AddSession(options => 
    { 
     options.IdleTimeout = TimeSpan.FromMinutes(30); 
     options.Cookie.HttpOnly = true; 
    }); 

    services.AddAuthentication(options => 
    { 
     options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; 
     options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; 
    }) 
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => 
    { 

     options.TokenValidationParameters = new TokenValidationParameters 
     { 
      ValidateIssuerSigningKey = true, 
      IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("mysupersecret_secretkey!123")), 
      ValidateIssuer = true, 
      ValidIssuer = "ExampleIssuer", 
      ValidateAudience = true, 
      ValidAudience = "ExampleAudience", 
      ValidateLifetime = true, 
      ClockSkew = TimeSpan.Zero, 
      SaveSigninToken = true 
     }; 
     options.Events = new JwtBearerEvents 
     { 
      OnTokenValidated = context => 
      { 
       JwtSecurityToken accessToken = context.SecurityToken as JwtSecurityToken; 
       if (accessToken != null) 
       { 
        ClaimsIdentity identity = context.Result.Principal.Identity as ClaimsIdentity; 
        identity?.AddClaim(new Claim("access_token", accessToken.RawData)); 
       } 

       return Task.CompletedTask; 
      } 
     }; 
    }) 
    .AddCookie(
      o => 
      { 
       o.Cookie.Name = "beareridentity"; 
       o.LoginPath = new PathString("/Home/Login/"); 
       o.AccessDeniedPath = new PathString("/Home/Login/"); 
      }); 

    services.AddMvc(); 

    services.AddTransient<IAccountService, AccountService>(); 
    services.AddTransient(typeof(ISession), serviceProvider => 
    { 
     var httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>(); 
     return httpContextAccessor.HttpContext.Session; 
    }); 
} 


public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
    loggerFactory.AddDebug(); 

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

    app.UseSession(); 
    app.UseStaticFiles(); 
    app.UseAuthentication(); 


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

,这里是我的登陆行动:

[HttpPost] 
public async Task<IActionResult> Login(LoginData data) 
{ 
    var loginresult = (await _accountService.GetLoginToken(data.Username, data.Password)); 

    if (!loginresult.Success) 
     return RedirectToAction("Login"); 

    Response.Cookies.Append("identity", loginresult.Token, new CookieOptions { Expires = DateTimeOffset.Now.Add 

    int id = await _getIdFromToken(loginresult); 

    ApplicationUser user; 
    await _signin(user = await _accountService.GetUserAsync(id)); 
    _session.SetData("actualuser", user); 

    return RedirectToAction("Index"); 
} 

private async Task _signin(ApplicationUser c) 
{ 
    var claims = new List<Claim> 
    { 
     new Claim(ClaimTypes.MobilePhone, c.Phone??""), 
     new Claim(ClaimTypes.Name, c.UserName) 
    }; 
    var userIdentity = new ClaimsIdentity(); 
    userIdentity.AddClaims(claims); 
    ClaimsPrincipal userPrincipal = new ClaimsPrincipal(userIdentity); 

    try 
    { 
     await HttpContext.SignInAsync(
      JwtBearerDefaults.AuthenticationScheme, 
      userPrincipal, 
      new Microsoft.AspNetCore.Authentication.AuthenticationProperties 
       { 
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20), 
        IsPersistent = true, 
        AllowRefresh = true, 
        IssuedUtc = DateTimeOffset.Now 
       }); 
    } 
    catch (Exception e) 
    { 
     throw; 
    } 
} 
+1

您是否阅读过以下内容:[使用ASP.NET核心中的Cookie进行JWT令牌身份验证](https://amanagrawal.blog/2017/09/18/jwt-token-authentication-with-cookies-in- ASP-网核心/)?我没有尝试过,但它看起来就是你想要做的。 –

+0

@FrankFajardo感谢您的链接。我将它实现到我的应用程序中,它现在可以工作。AYCS只有虚拟数据,所以我需要将虚拟数据转换为生产数据(来自我的服务/ api)。 –

+0

所以我假设回答你的问题。 AYCS是什么意思? –

这里的预建asp.net验证模块是如何博客文章您可以使用Cookie作为传递机制,对ASP.NET 2.0的核心,你的JWTs这正是你正在尝试做的: JWT Token Authentication with Cookies in ASP.NET Core

我还没有尝试过,但它可以指导你的理解,你可以正在做错了。

默认方案不匹配任何处理程序(在本例中为cookie)。如果可以的话,试试这个嵌入代码(这可能是.NET的核心2专用):

services.AddAuthentication("YourSchemeNameHere") 
.AddCookie("YourSchemeNameHere", options => 
{ 
    ... 
}); 

如果还是不行,在cookie的选项AuthenticationScheme属性更改为匹配DefaultAuthenticateScheme在身份验证选项。

+0

登录时仍然有相同的错误(我想我需要'JwtBearerDefaults.AuthenticationScheme'作为方案,因为我使用JWT)。另外,当我设置'AddAuthentication(JwtBearerDefaults.AuthenticationScheme)'并导航到'Home/Contact'时,我得到一个没有任何内容的白页。 (Debugmode在动作方法中设置了断点,但它从未击中它) –

我有类似的问题。 请检查Web.config并检查是否有节点,或检查是否有节点进行验证,可能是这个原因,或者配置不正确。

我开发一个MVC应用5,我的web配置是这样的

<modules> 
    <remove name="FormsAuthentication" /> 
    <remove name="ApplicationInsightsWebTracking" /> 
    <add name="ApplicationInsightsWebTracking" 
    type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, 
    Microsoft.AI.Web" preCondition="managedHandler" /> 
    </modules> 
<authentication mode="None" /> 

我使用他们的分贝