JWT令牌在dotnet core 2.1中返回失败

时间:2018-12-11 18:00:00

标签: .net-core

我想将jwt令牌发送到客户端。 但是当返回jwt令牌时,它会显示一些错误。 当我尝试登录时,就会发生此错误。 最初,我将项目数据库设置为sqlite,然后将其设置为mysql。我认为在更改数据库后会发生此问题 这是代码

启动类

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<DataContext>(s => s.UseMySql(Configuration.GetConnectionString("DefaultConnection")));

        IdentityBuilder builder = services.AddIdentityCore<User>(opt =>
        {
            opt.Password.RequireDigit = false;
            opt.Password.RequiredLength = 4;
            opt.Password.RequireNonAlphanumeric = false;
            opt.Password.RequireUppercase = false;
        });

        builder = new IdentityBuilder(builder.UserType, typeof(Role), builder.Services);
        builder.AddEntityFrameworkStores<DataContext>();
        builder.AddRoleValidator<RoleValidator<Role>>();
        builder.AddRoleManager<RoleManager<Role>>();
        builder.AddSignInManager<SignInManager<User>>();



        // services.AddAuthorization(options => {
        //     options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
        //     options.AddPolicy("SuperAdminPhotoRole", policy => policy.RequireRole("SuperAdmin"));
        // });

        services.AddMvc(options =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddJsonOptions(opt =>
        {
            opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        });
        services.AddCors();
        services.AddAutoMapper();
        services.AddTransient<Seed>();
        services.AddScoped<IAuthRepository, AuthRepository>();
        services.AddScoped<IDatingRepository, DatingRepository>();
          services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
          .AddJwtBearer(options =>
          {
              options.TokenValidationParameters = new TokenValidationParameters
              {
                  ValidateIssuerSigningKey = true,
                  IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
                    .GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                  ValidateIssuer = false,
                  ValidateAudience = false
              };
          });
          services.AddScoped<LogUserActivity>();

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, Seed seeder)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {

            app.UseExceptionHandler(builder =>
            {
                builder.Run(async context =>
                {
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

                    var error = context.Features.Get<IExceptionHandlerFeature>();
                    if (error != null)
                    {
                        context.Response.AddApplicationError(error.Error.Message);
                        await context.Response.WriteAsync(error.Error.Message);
                    }
                });
            });

            // app.UseHsts();
        }

        // app.UseHttpsRedirection();
        seeder.SeedUsers();
        app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
        app.UseStaticFiles();
        app.UseAuthentication();
        app.UseMvc();
    }
}

这是Auth控制器代码

[AllowAnonymous]
    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private readonly IAuthRepository _repo;
        private readonly IConfiguration _config;
        private readonly IMapper _mapper;
        private readonly UserManager<User> _userManager;
        private readonly SignInManager<User> _signInManager;

        public AuthController(IConfiguration config,
         IMapper mapper, UserManager<User> userManager,
         SignInManager<User> signInManager)
        {
            _signInManager = signInManager;
            _userManager = userManager;
            _config = config;
            _mapper = mapper;
        }

        [HttpPost("register")]
        public async Task<IActionResult> Register(UserForRegisterDto userForRegisterDto)
        {
            try
            {
                var userToCreate = _mapper.Map<User>(userForRegisterDto);
                var result = await _userManager.CreateAsync(userToCreate, userForRegisterDto.Password);
                var userToReturn = _mapper.Map<UserForDetailedDto>(userToCreate);

                if (result.Succeeded)
                {
                    return CreatedAtRoute("GetUser", new { Controller = "Users", id = userToReturn.Id }, userToReturn);
                }

                return BadRequest(result.Errors);

            }
            catch (Exception e)
            {
                return BadRequest("An error occurs while registering:" + e.ToString());
            }
        }

        [HttpPost("login")]
        public async Task<IActionResult> Login(UserForLoginDto userForLoginDto)
        {
            try
            {
                var user = await _userManager.FindByNameAsync(userForLoginDto.Username);
                var result = await _signInManager.CheckPasswordSignInAsync(user, userForLoginDto.Password, false);

                if (result.Succeeded)
                {
                    var appUser = await _userManager.Users.Include(p => p.Photos)
                    .FirstOrDefaultAsync(u => u.NormalizedUserName == userForLoginDto.Username.ToUpper());

                    var userToReturn = _mapper.Map<UserForListDto>(appUser);


                    return Ok(new
                    {
                        token = GenerateJwtToken(appUser),
                        user = userToReturn
                    });
                }

                return Unauthorized();
            }
            catch (Exception e)
            {
                return BadRequest("An error occurs while loggin:" + e.ToString());
            }

        }

        private async Task<string> GenerateJwtToken(User user)
        {
            var claims = new List<Claim> {
                new Claim(ClaimTypes.NameIdentifier,user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.UserName)
        };

            var roles = await _userManager.GetRolesAsync(user);

            foreach (var role in roles)
            {
                claims.Add(new Claim(ClaimTypes.Role, role));
            }

            var key = new SymmetricSecurityKey(Encoding.UTF8
            .GetBytes(_config.GetSection("AppSettings:Token").Value));

            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);

            var tokenDescripter = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(claims),
                Expires = DateTime.Now.AddDays(1),
                SigningCredentials = creds
            };

            var tokenHandler = new JwtSecurityTokenHandler();

            var token = tokenHandler.CreateToken(tokenDescripter);

                  return tokenHandler.WriteToken(token);
        }
    }

这是显示的错误

    Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HLJ0BIR31H6O", Request id "0HLJ0BIR31H6O:00000001": An unhandled exception was thrown by the application.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.PlatformNotSupportedException: This instance contains state that cannot be serialized and deserialized on this platform.
   at System.Security.Claims.ClaimsPrincipal.OnSerializingMethod(StreamingContext context)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at Newtonsoft.Json.Serialization.JsonContract.<>c__DisplayClass57_0.<CreateSerializationCallback>b__0(Object o, StreamingContext context)
   at Newtonsoft.Json.Serialization.JsonContract.InvokeOnSerializing(Object o, StreamingContext context)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.OnSerializing(JsonWriter writer, JsonContract contract, Object value)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)

1 个答案:

答案 0 :(得分:3)

return Ok(new {
                        token = GenerateJwtToken(appUser).Result,
                        user = userToReturn
              });

由于GenerateJwtToken是异步方法,因此您需要获取结果。这应该可以解决您的问题。

谢谢