AuthorizeAttribute与.NET Core 2.0中的JWT令牌 - 身份验证

时间:2017-10-12 12:45:03

标签: c# asp.net-web-api asp.net-core jwt

我在运行.net core 2.0的Web-API中实现了JWT Bearer Token-Authentication。 现在我创建了另一个与我的Web-API对话的网站。检索令牌有效,我将其添加到cookie中,当我调试时,我可以看到我的cookie(名称是“identity”)具有正确的值。

在项目模板中,控制器HomeController包含操作。我正在将Contact用于我的目的,并使用AuthorizeAttribute对其进行注释:

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

    return View();
}

现在我正在(作为匿名用户)导航到/home/contact - 完美:它将我重定向到我需要登录的/home/login

当我尝试登录时,我收到以下错误消息:

  

没有IAuthenticationSignInHandler配置为处理该方案的登录:Bearer

我想令牌配置是错误的 - 我想还有一些我在这里做错的事情。

首先,这是我的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;
    }
}

3 个答案:

答案 0 :(得分:2)

这是一篇关于如何在ASP.NET Core 2.0上使用cookie作为JWT的传递机制的博客文章,您正在尝试这样做: JWT Token Authentication with Cookies in ASP.NET Core

我没有尝试过,但它可以指导你理解你做错的地方。

答案 1 :(得分:0)

默认方案与任何处理程序都不匹配(在本例中为cookie)。如果可以,请尝试将其插入到您的代码中(这可能是.net core 2特定的):

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

如果这不起作用,请更改cookie选项中的AuthenticationScheme属性以匹配身份验证选项中的DefaultAuthenticateScheme。

答案 2 :(得分:0)

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

我正在开发一个mvc 5应用程序,我的网络配置就像这样

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

我正在使用预先构建的asp.net身份验证模块及其db