Could you please give me a hint if there is a way to protect the whole Web API by making it accessible only to a defined set of IP addresses? Thank you very much for your great support!
Perfect - thank you very much.
Thank you very much - that was the problem!
Is my code ok or is there a better way to solve it?
Solution.Web.MultiTenancy.TenantIdAccessor.cs:
public void SetCurrentTenantId()
{
var tenancyName = _tenancyNameFinder.Value.GetCurrentTenancyNameOrNull();
CurrentTenantId = GetVerifiedTenantIdOrNull();
}
private int? GetVerifiedTenantIdOrNull()
{
var tenantIdFromClient = GetFromHeaderOrNull();
if (tenantIdFromClient != null)
{
return _tenantCache.GetOrNull(tenantIdFromClient.Value)?.Id;
}
return null;
}
private int? GetFromHeaderOrNull()
{
if (HttpContext.Current == null)
{
return null;
}
if(HttpContext.Current.Request.Headers.GetValues("Abp.TenantId") == null)
{
return null;
}
var header = HttpContext.Current.Request.Headers.GetValues("Abp.TenantId").GetValue(0).ToString();
if (string.IsNullOrWhiteSpace(header))
{
return null;
}
int tenantId;
return int.TryParse(header, out tenantId) ? (int?)tenantId : null;
}
It seems that it does not work with repositories based on entities that are defined in the project - I have done the following test to check it: I have changed the build in GetUserChatMessages from ChatAppService and changed it to:
[AbpAllowAnonymous]
public async Task<ListResultDto<ChatMessageDto>> GetUserChatMessages(GetUserChatMessagesInput input)
{
//var userId = AbpSession.GetUserId();
//var messages = await _chatMessageRepository.GetAll()
// .WhereIf(input.MinMessageId.HasValue, m => m.Id < input.MinMessageId.Value)
// .Where(m => m.UserId == userId && m.TargetTenantId == input.TenantId && m.TargetUserId == input.UserId)
// .OrderByDescending(m => m.CreationTime)
// .Take(50)
// .ToListAsync();
var messages = await _chatMessageRepository.GetAll().Where(m=>m.UserId == 2).ToListAsync();
messages.Reverse();
return new ListResultDto<ChatMessageDto>(messages.MapTo<List<ChatMessageDto>>());
}
The result is the same as for my own AppService class - not a single result row for anonymous users. You can call it anonymously, it jumps into the method in debug, you can step through the code until the end of the method but the repository always delivers 0 result rows from database - until you sign in with a user and repeat it - then you get the results you expect.
So where do I have to change what to allow anonymous access to the repositories? Thank you very much.
Thank you - I have already tried this with several of my repositories. They all deliver 0 items until I sign in. No not authorized or error messages just 0 items.
Additional info - I have added the _userRoleRepository to my class and I am able to retrieve results anonymously. But where could be the difference between my own repositories and the ABP ones? Thanks!
OK, I have checked logs and debugged - and now I am sure that the only problem I hit is that I cannot use repositories to access database. All repositories deliver 0 results. When I sign in to the backend and trigger the method again, than the repositories deliver the results.
Do I have to define anonymous access somewhere else to get the repositories working? Very strange about this behaviour is the fact that the GetUsers method works with repositories too and does not run into problems. I have compared the structure of my own service class and the UserAppService class and cannot find differences.
Thank you!
Thank you for your hints. Using it with the GetUsers method works for me too.
I am using Abp.1.0.0.0. There is much info inlucded in the code that should not get public, so I am not able to share it at the moment.
I am not using [AbpAuthorize] and cannot access the method - is that a hint, that something is generally configured wrong? I am getting "500 Internal Server Error" and not "401 Unauthorized".
Great and easy to understand explanation! Thank you very much!
Thank you very much and no problem ;)
I want to make it available in multiple pages and use the SPA - so I put it in Web/App/common/layout/layout.cshtml, right?
Thanks!