I have a problem I don't know where , after setting authorization header of HttpClient
return internal server error 500
.
Auth Controller Login Action
namespace MagicVilla_Web.Controllers
{
public class AuthController : Controller
{
private readonly IAuthService _authService;
public AuthController(IAuthService authService)
{
_authService = authService;
}
[HttpGet]
public IActionResult Login()
{
LoginRequestDTO loginRequestDTO = new LoginRequestDTO();
return View(loginRequestDTO);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginRequestDTO loginRequestDTO)
{
APIResponse response = await _authService.LoginAsync<APIResponse>(loginRequestDTO);
if (response != null && response.IsSuccess)
{
LoginResponseDTO model = JsonConvert.DeserializeObject<LoginResponseDTO (Convert.ToString(response.Result));
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.Name, model.User.Name));
identity.AddClaim(new Claim(ClaimTypes.Role, model.User.Role));
var principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
HttpContext.Session.SetString(SD.SessionToken, model.Token);
return RedirectToAction("Index","Home");
}
else
{
ModelState.AddModelError("CustomError", response.ErrorMessages.FirstOrDefault());
return View(loginRequestDTO);
}
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterationRequestDTO registerationRequestDTO)
{
APIResponse result = await _authService.RegisterAsync<APIResponse>(registerationRequestDTO);
if (result != null && result.IsSuccess)
{
return RedirectToAction("Login");
}
return View();
}
[HttpGet]
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync();
HttpContext.Session.SetString(SD.SessionToken, "");
return RedirectToAction("Index", "Home");
}
[HttpGet]
public async Task<IActionResult> AccessDenied()
{
return View();
}
}
}
Home Controller Index
namespace MagicVilla_Web.Controllers
{
public class HomeController : Controller
{
private readonly IVillaService villaService;
private readonly IMapper mapper;
public HomeController(IVillaService villaService, IMapper mapper)
{
this.villaService = villaService;
this.mapper = mapper;
}
public async Task<IActionResult> Index()
{
List<VillaDTO> list = new();
var response = await villaService.GetAllAsync<APIResponse>(HttpContext.Session.GetString(SD.SessionToken));
if (response != null && response.IsSuccess)
{
list = JsonConvert.DeserializeObject<List<VillaDTO>>(Convert.ToString(response.Result));
}
return View(list);
}
}
}
GetAllAsync From VillaService.cs
public class VillaService : BaseService , IVillaService
{
private readonly IHttpClientFactory clientFactory;
private string villaUrl;
public VillaService(IHttpClientFactory clientFactory, IConfiguration configuration) : base(clientFactory)
{
this.clientFactory = clientFactory;
this.villaUrl = configuration.GetValue<string>("ServiceUrls:VillaAPI");
}
public Task<T> GetAllAsync<T>(string token)
{
return SendAsync<T>(new APIRequest
{
ApiType = SD.ApiType.GET,
Url = this.villaUrl + "/api/VillaAPI",
Token = token
});
}
}
Send Async From BaseService.cs
Here response return internal server error 500 after pass the token in the header Authrization & not going to API endpoint .
namespace MagicVilla_Web.Services
{
public class BaseService : IBaseServices
{
public APIResponse APIResponse { get; set; }
public IHttpClientFactory httpClient { get; set; }
public BaseService(IHttpClientFactory httpClient)
{
this.APIResponse = new();
this.httpClient = httpClient;
}
public async Task<T> SendAsync<T>(APIRequest apiRequest)
{
try
{
var client = httpClient.CreateClient("MagicAPI");
HttpRequestMessage request = new HttpRequestMessage();
request.Headers.Add("Accept", "application/json");
request.RequestUri = new Uri(apiRequest.Url);
if (apiRequest.Data != null)
{
request.Content = new StringContent(JsonConvert.SerializeObject(apiRequest.Data), Encoding.UTF8, "application/json");
}
switch (apiRequest.ApiType)
{
case SD.ApiType.POST:
request.Method = HttpMethod.Post;
break;
case SD.ApiType.PUT:
request.Method = HttpMethod.Put;
break;
case SD.ApiType.DELETE:
request.Method = HttpMethod.Delete;
break;
default:
request.Method = HttpMethod.Get;
break;
}
HttpResponseMessage response = null;
if (!string.IsNullOrEmpty(apiRequest.Token))
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiRequest.Token);
}
response = await client.SendAsync(request);
var apiContent = await response.Content.ReadAsStringAsync();
try
{
APIResponse apiResponse = JsonConvert.DeserializeObject<APIResponse>(apiContent);
if ((response.StatusCode == System.Net.HttpStatusCode.BadRequest || response.StatusCode == System.Net.HttpStatusCode.NotFound))
{
apiResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
apiResponse.IsSuccess = false;
var apiResponseSerialized = JsonConvert.SerializeObject(apiResponse);
var apiResponseDeserialized = JsonConvert.DeserializeObject<T>(apiResponseSerialized);
return apiResponseDeserialized;
}
}
catch (Exception e)
{
var exceptionResponse = JsonConvert.DeserializeObject<T>(apiContent);
return exceptionResponse;
}
var APIResponse = JsonConvert.DeserializeObject<T>(apiContent);
return APIResponse;
}
catch (Exception e)
{
var dto = new APIResponse
{
ErrorMessages = new List<string> { Convert.ToString(e.Message) },
IsSuccess = false
};
var res = JsonConvert.SerializeObject(dto);
var apiResponse = JsonConvert.DeserializeObject<T>(res);
return apiResponse;
}
}
}
}
VillaAPI Controller
[Route("api/[controller]")]
[ApiController]
public class VillaAPIController : ControllerBase
{
public readonly IVillaRepository villaRepository;
public readonly IMapper mapper;
protected APIResponse response;
public VillaAPIController(IVillaRepository villaRepository, IMapper mapper)
{
this.villaRepository = villaRepository;
this.mapper = mapper;
this.response = new();
}
[HttpGet]
[Authorize]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<IEnumerable<APIResponse>>> GetVillas()
{
try
{
IEnumerable<Villa> villaList = await villaRepository.GetAllAsync();
response.Result = mapper.Map<List<VillaDTO>>(villaList);
response.StatusCode = System.Net.HttpStatusCode.OK;
}
catch (Exception ex)
{
response.IsSuccess = false;
response.ErrorMessages = new List<string> { ex.Message };
}
return Ok(response);
}
}
Program.cs API
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContext<ApplicationDbContext>(o => {
o.UseSqlServer(builder.Configuration.GetConnectionString("DefaultSQLConnection"));
});
builder.Services.AddAutoMapper(typeof(MappingConfig));
builder.Services.AddScoped<IVillaRepository, VillaRepository>();
builder.Services.AddScoped<IVillaNumberRepository, VillaNumberRepository>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddControllers(o => {
//o.ReturnHttpNotAcceptable = true;
}).AddNewtonsoftJson().AddXmlDataContractSerializerFormatters();
builder.Services.AddEndpointsApiExplorer();
//get secret key from appSittings.json
var key = builder.Configuration.GetValue<string>("ApiSettings:Secret");
//add Authentication Configurations
builder.Services.AddAuthentication(x =>
{
//configure the default authentication scheme and the default challenge scheme. Both of them we want to use JWT bearer defaults
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
//we have something called as add JWT bearer and then we can configure options on that.
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false; //we have the required https metadata
x.SaveToken = true; //save the token
x.Authority = "https://localhost:7003/";
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(key)),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,
};
});
//to enable bearer in swagger
builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description =
"JWT Authorization header using the Bearer scheme. \r\n\r\n " +
"Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\n" +
"Example: \"Bearer 12345abcdef\"",
Name = "Authorization",
In = ParameterLocation.Header,
Scheme = "Bearer"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Scheme = "oauth2",
Name = "Bearer",
In = ParameterLocation.Header
},
new List<string>()
}
});
});
//app => configured application
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Program.cs Web
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddAutoMapper(typeof(MappingConfig));
builder.Services.AddHttpClient<IVillaService, VillaService>();
builder.Services.AddScoped<IVillaService, VillaService>();
builder.Services.AddHttpClient<IVillaNumberService, VillaNumberService>();
builder.Services.AddScoped<IVillaNumberService, VillaNumberService>();
builder.Services.AddHttpClient<IAuthService, AuthService>();
builder.Services.AddScoped<IAuthService, AuthService>();
builder.Services.AddDistributedMemoryCache();
IdentityModelEventSource.ShowPII = true;
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.SlidingExpiration = true;
options.LoginPath = "/Auth/Login";
options.AccessDeniedPath = "/Auth/AccessDenied";
});
//add authorization
//builder.Services.AddAuthorization();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(100);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/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.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
If I turn off the authorization and not send the token in the header, everything works fine .MagicVilla_VillaAPI this project link in Github :https://github.com/MoZytoon/MagicVilla
The problem was with the program.cs file for the Api. here :
x. Authority = "https://localhost:7003/";
When setting the the AddAuthentication .