Am trying to create basic register and login authentication, when I run my app everything works and my swagger interface pops up, testing the register end point gives me the error below, the exception tells me that it has something to do with my token validation parameters having a null value but I don't get how that can be.
> System.ArgumentNullException: String reference not set to an instance
> of a String. (Parameter 's') at System.Text.Encoding.GetBytes(String
> s) at
> X_Change_Api.Installers.Dbinstaller.<>c__DisplayClass0_0.b__4(JwtBearerOptions x) in C:\Users\Iron
> Man\source\repos\X_Change_Api\X_Change_Api\Installers\Dbinstaller.cs:line
> 55 at
> Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String
> name, TOptions options) at
> Microsoft.Extensions.Options.OptionsFactory`1.Create(String name) at
> Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass11_0.b__0()
> at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of
> stack trace from previous location where exception was thrown --- at
> System.Lazy`1.CreateValue() at System.Lazy`1.get_Value() at
> Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name,
> Func`1 createOptions) at
> Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name) at
> Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme
> scheme, HttpContext context) at
> Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext
> context, String authenticationScheme) at
> Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext
> context, String scheme) at
> Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext
> context) at
> Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext
> httpContext) at
> Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext
> httpContext, ISwaggerProvider swaggerProvider) at
> Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext
> context) HEADERS ======= Accept: */* Accept-Encoding: gzip, deflate,
> br Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 Host: localhost:5001
> Referer: https://localhost:5001/swagger/index.html User-Agent:
> Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
> like Gecko) Chrome/84.0.4147.105 Safari/537.36 :method: GET
> :authority: localhost:5001 :scheme: https :path:
> /api/v1/identity/Register?Email=589tghrv&Password=feufeivw&User_Name=4huivnfgi
> sec-fetch-site: same-origin sec-fetch-mode: cors sec-fetch-dest:
> empty
//Startup.cs
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)
{
var instalation = typeof(Startup).Assembly.ExportedTypes.
Where(x => typeof(IInstaller).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract).Select(Activator.CreateInstance).Cast<IInstaller>().ToList();
instalation.ForEach(instal => instal.Cleanner(Configuration, services));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseSwagger();
app.UseSwaggerUI(p => p.SwaggerEndpoint("/swagger/v1/swagger.Json", "TXC"));
app.UseRouting();
app.UseAuthentication();
var Raphael = new Swagger_sett();
Configuration.GetSection(nameof(Startup)).Bind(Raphael);
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
//Installer class
public class In_App_Componentes : IInstaller
{
public void Cleanner(IConfiguration configuration, IServiceCollection services)
{
services.AddControllers().AddNewtonsoftJson(p => p.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
services.AddScoped<IX_Change, The_center>();
services.AddScoped<IIdentify, Identify>();
}
}
//Other installer class
public class Dbinstaller : IInstaller
{
public void Cleanner(IConfiguration configuration, IServiceCollection services)
{
var jwt = new Mystery();
configuration.Bind(key:nameof(jwt), jwt);
services.AddSingleton(jwt);
services.AddDbContext<DataContext>(opt =>
opt.UseSqlServer(configuration.GetConnectionString("TXC Connection")));
services.AddIdentityCore<IdentityUser>();
services.AddIdentity<IdentityUser, IdentityRole>(option =>
{
option.Password.RequireDigit = true;
option.Password.RequireLowercase = true;
option.Password.RequiredLength = 8;
}).AddEntityFrameworkStores<DataContext>().AddDefaultTokenProviders();
services.AddMvc(x =>
{
x.EnableEndpointRouting = false;
}).SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwt.Secret)),
ValidateIssuer = false,
ValidateAudience = false,
RequireExpirationTime = false,
ValidateLifetime = true
};
});
services.AddSwaggerGen(x =>
{
x.SwaggerDoc("v1", new OpenApiInfo { Title = "TXC API", Version = "v1" });
x.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description="JWT Authorization Header using the bearer scheme",
Name="Authorization",
In=ParameterLocation.Header,
Type=SecuritySchemeType.ApiKey
});
x.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{new OpenApiSecurityScheme{Reference=new OpenApiReference
{
Id="Bearer",
Type=ReferenceType.SecurityScheme
}
},new List<string>() }
});
});
}
}
//Register/Login controller
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class IdentifyMe : Controller
{
private readonly IIdentify _identify;
private readonly Users _member;
public IdentifyMe(IIdentify identifying, Users users)
{
_identify = identifying;
_member = users;
}
[HttpGet(Api_Routes.Identity.Register)]
public async Task<IActionResult> Register(UserRegistration register)
{
var members = _member.Email.ToList();
var individual = members.FirstOrDefault(x => x.Equals(register.Email)).ToString();
if (!ModelState.IsValid)
{
return BadRequest(new Unauthenticated
{
Errors=ModelState.Values.SelectMany(x=>x.Errors.Select(xx=>xx.ErrorMessage))
});
}
var authresponce = await _identify.RegisterAsync(register.Email, register.Password, register.User_Name);
if (!authresponce.Success)
{
return BadRequest(new Unauthenticated
{
Errors = authresponce.Errors
});
}
return Ok(new Authenticated
{
Token = authresponce.Token
});
}
[HttpGet(Api_Routes.Identity.Login)]
public async Task<IActionResult> LoginAsync(User_login login)
{
var authresponce = await _identify.LoginAsync(login.email, login.Password);
if (!authresponce.Success)
{
return BadRequest(new Unauthenticated
{
Errors = authresponce.Errors
});
}
return Ok(new Authenticated
{
Token = authresponce.Token
});
}
}
//Token generation class
public class Identify : IIdentify
{
private readonly UserManager<IdentityUser> _manager;
private readonly Mystery _jwtset;
public Identify(UserManager<IdentityUser> userManager, Mystery jW)
{
_manager = userManager;
_jwtset = jW;
}
public async Task<Authentication_result> RegisterAsync(string email, string password, string Username)
{
var exists = _manager.FindByEmailAsync(email);
if (exists != null)
{
return new Authentication_result
{
Errors = new[] { "User with this email already exists" }
};
}
var newPerson = new IdentityUser
{
Email = email,
UserName = Username
};
var Creation = await _manager.CreateAsync(newPerson, password);
if (!Creation.Succeeded)
{
return new Authentication_result
{
Errors = new[] { "Invalid user!" }
};
}
return Generate_Authentication_Result(newPerson);
}
public async Task<Authentication_result> LoginAsync(string email, string Password)
{
var user = await _manager.FindByEmailAsync(email);
if (user == null)
{
return new Authentication_result
{
Errors = new[] { "User does not exists" }
};
}
var validate_password = await _manager.CheckPasswordAsync(user, Password);
if (!validate_password)
{
return new Authentication_result
{
Errors = new[] { "" }
};
}
return Generate_Authentication_Result(user);
}
private Authentication_result Generate_Authentication_Result(IdentityUser newPerson)
{
var Tokenhandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_jwtset.Secret);
var TokenDescripter = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(JwtRegisteredClaimNames.Sub, newPerson.Email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Email, newPerson.Email),
new Claim("id",newPerson.Id)
}),
Expires = DateTime.UtcNow.AddHours(2),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = Tokenhandler.CreateToken(TokenDescripter);
return new Authentication_result
{
Success = true,
Token = Tokenhandler.WriteToken(token)
};
}
}