I have a problem with the identity server. It sends a few identity server methods to each request after just a few minutes when I sign in with the identity server manager. Actually, it doesn't need those requests, but it sends them. I don't use HttpContext.User things related to the Indentity Server... In every single of my request to any Controllers Action, it's first querying to Identity tables like; AspNetUsers, AspNetUserClaims, AspNetRoles, AspNetRoleClaims.
Example of ProblemController Constructor like;
private readonly IProblemService _problemService;
public ProblemsController(IProblemService problemService)
{
_problemService = problemService;
}
Manager;
public class ProblemManager : ServiceBase<
IProblemRepository,
IProblemServiceResource,
Problem>, IProblemService
{
private readonly IIdentityRepository _identityRepository;
private readonly IStringLocalizer<MainResource> _localizer;
private readonly IServiceResources _genericServiceResources;
protected IHttpContextAccessor HttpContextAccessor { get; }
int userID = 0;
public ProblemManager(
IUnitOfWorkFactory unitOfWorkFactory,
IProblemRepository genericRepository,
IProblemServiceResource problemServiceResource,
IIdentityRepository identityRepository,
IRedisServer _caching,
IMapper _mapper,
IStringLocalizer<MainResource> localizer,
IHttpContextAccessor httpContextAccessor,
IServiceResources genericServiceResources) : base(unitOfWorkFactory, genericRepository, _caching, _mapper, problemServiceResource, problemServiceResource, localizer)
{
this.HttpContextAccessor = httpContextAccessor;
userID = JwtTools.JwtDecodeManager.JwtDecode(HttpContextAccessor);
_genericServiceResources = genericServiceResources;
}
public async Task<IDataResult<IEnumerable<ProblemListResponseDto>>> GetMostViewedProblems(int? pageNumber, int? filter = 3)
{
IEnumerable<ProblemListResponseDto> list;
if (pageNumber.HasValue)
{
list = await _caching.LoadExchange(async () => await Repository.GetMostViewedProblems(pageNumber.Value, filter.Value), CacheKeys.GetMostViewedProblems + "" + CacheSubKeys._PageNumber_ + pageNumber.Value);
if (list != null)
return new SuccessDataResult<IEnumerable<ProblemListResponseDto>>(list);
else
return new ErrorDataResult<IEnumerable<ProblemListResponseDto>>(new List<string> { ServiceResources.ProblemDoesNotExist().Description }, ServiceResources.ProblemDoesNotExist().Code);
}
}
Repository;
private readonly FooContext _context;
public ProblemRepository(FooContext context) : base(context)
{
_context = context;
}
public async Task<Problem> GetProblemWithAttachment(int userID, int problemID)
{
var query = await _context.Problems.Include(n => n.ProblemAttachments).Where(n => n.ProblemID == problemID && n.AppUser.IsActive).FirstOrDefaultAsync();
return query;
}
public async Task<IEnumerable<ProblemListResponseDto>> GetMostViewedProblems(int? pageNumber, int? filter = 3)
{
IEnumerable<ProblemListResponseDto> query;
if (pageNumber.HasValue)
{
query = await _context.Problems.Include(n => n.AppUser).Include(n => n.Brand).Include(n => n.ProblemAttachments).Include(n => n.ProblemFollows).Include(n => n.ProblemSupportCount).Include(n => n.ProblemBookmarks).Include(n => n.ProblemViewCount)
.Where(n => (n.ProblemStatus == (int)Enums.Status.Published || n.ProblemStatus == (int)Enums.Status.Solved || n.ProblemStatus == (int)Enums.Status.Answered) && n.ProblemViewCount.ViewCount > 0 && n.AppUser.IsActive)
.OrderByDescending(x => x.ProblemViewCount.ViewCount)
.Skip(PageSize * (pageNumber.Value - 1)).Take(filter.Value)
.Select(x => new ProblemListResponseDto
{
ProblemID = x.ProblemID,
Name = x.Name,
Description = x.Description,
ViewCount = x.ProblemViewCount.ViewCount > 0 ? x.ProblemViewCount.ViewCount : 0,
ProblemSupportCount = x.ProblemSupportCount.SupportCount > 0 ? x.ProblemSupportCount.SupportCount : 0,
AppUserName = x.AppUser.Name,
AppUserUserName = x.AppUser.UserName,
PhotoPath = string.IsNullOrEmpty(x.AppUser.PhotoPath),
BrandName = x.Brand.Name,
BrandLogo = string.IsNullOrEmpty(x.Brand.Logo),
BrandUrl = x.Brand.Url,
ProblemAttachments = x.ProblemAttachments.Select(n => new ProblemAttachmentDto
{
AttachmentTypeID = n.AttachmentTypeID,
ProblemAttachmentID = n.ProblemAttachmentID,
ProblemID = n.ProblemID,
Path = n.Path,
CreatedDate = n.CreatedDate,
ModifiedDate = n.ModifiedDate,
}).ToList()
}).AsNoTracking().ToListAsync();
return query;
}
return null;
}
My Context inherited from IdentityDbContext;
public partial class FooContext : IdentityDbContext<AppUser, AppRole, int>
Startup Configuration About Authentication, JWT and Identity;
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwt =>
{
jwt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(new HMACSHA512(Encoding.UTF8.GetBytes(_jwtInfo.SecurityKey)).Key),
ValidateIssuer = false,
ValidateAudience = false,
RequireExpirationTime = false,
ValidateLifetime = true,
ValidIssuer = _jwtInfo.Issuer,
ValidAudience = _jwtInfo.Audience,
ClockSkew = TimeSpan.FromMinutes(0)
};
});
services.AddIdentity<AppUser, AppRole>().AddEntityFrameworkStores<FooContext>().AddErrorDescriber<LocalizedIdentityErrorDescriber>()
.AddDefaultTokenProviders();
Startup Configure Method is like;
app.UseCookiePolicy();
app.UseSession();
var supportedCultures = new[] { "tr-TR", "en", "de", "ru", "ko" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
app.UseHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse,
});
app.UseMiniProfiler();
loggerFactory.AddNLog();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Foo.WebApi v1");
});
if (!env.IsDevelopment())
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseMiddleware<ExceptionHandlingMiddleware>();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseStatusCodePages();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
And Finally JwtDecode method;
public static int JwtDecode(IHttpContextAccessor httpContextAccessor)
{
StringValues values;
httpContextAccessor.HttpContext.Request.Headers.TryGetValue("Authorization", out values);
var token = values.ToString().Split(' ');
if (token.Length > 1)
{
var handler = new JwtSecurityTokenHandler();
try
{
var securityToken = handler.ReadToken(token.Last());
var jwtToken = securityToken as JwtSecurityToken;
if (!IsValid(token.Last()))
{
return 0;
}
else
return Convert.ToInt32(jwtToken.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value);
}
catch (SecurityTokenExpiredException ex)
{
return 0;
}
}
return 0;
}
/Api/Home/ProductList
{
//**Querying AspNetUsers, AspNetUserClaims, AspNetRoles, AspNetRoleClaims.**
//return ProductRepository.ProductList;
}
Maybe it's happenning befor the action call, maybe inside the Dependency Injection, maybe at the action Attribute. The attribute of the action is like;
[HttpPost("[action]")]
[Authorize(AuthenticationSchemes = "Bearer", Roles = Role.Member)]
You can look at the below image to see the requests. Mini Profiler Request Detail
I want only the request related tables is going to get from Database.
/Api/Home/ProductList
{
//**Get ProductList Only**
//return ProductRepository.ProductList;
}
I can share any other details if you want..
What is the missing point do you think?
EDIT: The problem was because of the cookie integration. I removed cookie integration part, and it doesn't send requests with Identity tables anymore. But I am wondering, I use tokens for authorization control, should I use the cookie integration or how can I use kind of true? My cookie integration code is below:
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = "auth_cookie";
options.Cookie.SameSite = SameSiteMode.Lax;
options.LoginPath = string.Empty;
options.AccessDeniedPath = new PathString("/api/contests");
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
};
});
At the same time, I also removed this configure code line:
app.UseCookiePolicy();