代码之家  ›  专栏  ›  技术社区  ›  user581157

来自postman的JWT令牌从不使用Authorize属性命中控制器

  •  0
  • user581157  · 技术社区  · 6 年前

    试图了解JWT是如何为asp.net核心应用程序。我用一个ASP.NETMVC核心应用程序模板。 enter image description here

    我的启动.csJWT令牌的约束配置:

     public class Startup
    {
         // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors();
            services.AddAuthentication(sharedOptions =>
            {
                sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["Jwt:Issuer"],
                    ValidAudience = Configuration["Jwt:Issuer"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
                };
    
                //options.EventsType = typeof(AuthenticateCustomEvent);
            });
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
            // In production, the React files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/build";
            });
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseAuthentication();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
    
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();
    
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });
    
            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";
    
                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });
        }
    }
    

    我的登录控制器包含代码,用于在成功验证用户时返回令牌这将返回一个令牌,如下所示

    enter image description here

    1 回复  |  直到 6 年前
        1
  •  0
  •   sebu    6 年前

    我下面的解决方案有点不同,但这个解决方案将帮助您处理自定义身份验证实现,您可以为不同类型的用户实现不同类型的身份验证。如果需要在API项目下创建类AuthorizationRequiredAttribute,则该类将继承 类来过滤每个API请求。您可以过滤所有的HTTP方法(GET、POST、PUT、DELETE…等等),并且可以为特定的HTTP方法实现您自己的授权逻辑。

    A过滤属性.cs

    using BillSyatemCore.Common.Constants;
    using BillSyatemCore.Services.Authentication;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Microsoft.Extensions.Configuration;
    using System;
    using System.IdentityModel.Tokens.Jwt;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    
    namespace BillSyatemCore.Handlers
    {
        [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
        public class AuthorizationRequiredAttribute : ActionFilterAttribute
        {
            private IConfiguration _config;
            public AuthorizationRequiredAttribute(IConfiguration config)
            {
                _config = config;
            }
            public override void OnActionExecuting(ActionExecutingContext context)
            {
                try
                {
                    if (context.HttpContext.Request.Headers.ContainsKey(Constants.HttpHeaders.Token))
                    {
                        var handler = new JwtSecurityTokenHandler();
                        var token = handler.ReadToken(context.HttpContext.Request.Headers[Constants.HttpHeaders.Token])
                            as JwtSecurityToken;
                        var expireDate = Convert.ToDateTime(token.Claims.First(claim => claim.Type == Constants.JwtClaims.ExpiresOn).Value);
                        if (context.HttpContext.Request.Method == WebRequestMethods.Http.Get)
                        {
                            if (expireDate < DateTime.Now)
                            {
                                context.Result = new UnauthorizedResult();
                            }
                        }
                        else
                        {
    
                            //You may filter post,put,delete etc request here.  
                        }
                    }
                    else
                    {
                        context.Result = new NotFoundResult();
                    }
                }
                catch (Exception ex)
                {
                    context.Result = new BadRequestResult();
                }
                base.OnActionExecuting(context);
            }
        }
    }
    

    启动.cs

    public void ConfigureServices(IServiceCollection services)
    {
        //JWT
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = Configuration["Jwt:Issuer"],
                ValidAudience = Configuration["Jwt:Issuer"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
            };
        });
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials()
            .Build());
        });
    
    }
    

    控制器.cs

    using BillSyatemCore.Models.Authentication;
    using BillSystemCore.Transporter;
    using Microsoft.AspNetCore.Mvc;
    
    namespace TestProject.Controllers
    {
        [Produces("application/json")]
        [Route("api/[controller]")]
        public class UserTypeController : Controller
        {
            private readonly IAuthTransporter _authTransporter;
            public UserTypeController(IAuthTransporter authTransporter)
            {
                _authTransporter = authTransporter;
            }
            [HttpPost("save"), ServiceFilter(typeof(AuthorizationRequiredAttribute))]
            public IActionResult Save([FromBody] UserType userType)
            {
                return Ok(_authTransporter.UserTypeServices.Save(userType));
            }
        }
    }