- Входит в систему, введя имя и пароль. Сервер возвращает носителя jwt, который используется Frontend для аутентификации каждого запроса Ajax с Person1
- Создает ресурс1. Frontend перенаправления в/resources/1
- Созданный Resource1 с другом по электронной почте. Друг должен быть в состоянии получить к нему доступ к нему анонимно, не создавая учетную запись
public class PersonController : ControllerBase
{
[AllowAnonymous]
public LoggedInPersonDto Login(string name, string password)
{
PersonEntity personEntity = dataAccess.Person(name, password);
var personIdentity = new PersonIdentity(personEntity);
string jwt = personIdentity.ToJwt();
return new LoggedInPersonDto(jwt);
}
}
[Authorize]
public class ResourceController : ControllerBase
{
public ResourceDto Resource(int id)
{
var personIdentity = new PersonIdentity(HttpContext.User.Claims);
ResourceEntity resourceEntity = dataAccess.Resource(id, personIdentity.PersonId);
return ResourceDto.ToDto(resourceEntity);
}
}
UPDATE 1
I couldn't find any web patterns for situation presented above.
My initial solution was to encrypt resource ids with Microsoft.AspNetCore.DataProtection.IDataProtectionProvider and use a different Controller for access:
public class ResourceService
{
public ResourceDto Resource(int id, PersonIdentity personIdentity)
{
ResourceEntity resourceEntity = dataAccess.Resource(id, personIdentity.PersonId);
return ResourceDto.ToDto(resourceEntity);
}
public void DoSomethingWithResource(int id, PersonIdentity personIdentity)
{
}
}
[Authorize]
public class ResourceController : ControllerBase
{
private readonly ResourceService service;
public ResourceController(ResourceService service)
{
this.service = service;
}
public ResourceDto Resource(int id)
{
var personIdentity = new PersonIdentity(HttpContext.User.Claims);
return service.Resource(id, personIdentity);
}
public void DoSomethingWithResource(int id)
{
var personIdentity = new PersonIdentity(HttpContext.User.Claims);
return service.DoSomethingWithResource(id, personIdentity);
}
}
[AllowAnonymous]
public class ResourceForAnonymousController : ControllerBase
{
private readonly ResourceService service;
public ResourceForAnonymousController(ResourceService service)
{
this.service = service;
}
[Authorize]
public string EncryptId(int id, [FromServices] IDataProtectionProvider dataProtectionProvider)
{
var personIdentity = new PersonIdentity(HttpContext.User.Claims);
var encryptedId = new EncryptableId() { Id = id, PersonId = personIdentity.PersonId };
return encryptedId.Encrypt(dataProtectionProvider.CreateProtector("default"));
}
public ResourceDto Resource(string encryptedId, [FromServices] IDataProtectionProvider dataProtectionProvider)
{
EncryptableId decryptedId = EncryptableId.Decrypt(string encryptedId, dataProtectionProvider.CreateProtector("default"));
var personIdentity = new PersonIdentity(decryptedId.PersonId);
return service.Resource(decryptedId.Id, personIdentity);
}
public void DoSomethingWithResource(string encryptedId, [FromServices] IDataProtectionProvider dataProtectionProvider)
{
EncryptableId decryptedId = EncryptableId.Decrypt(encryptedId, dataProtectionProvider.CreateProtector("default"));
var personIdentity = new PersonIdentity(decryptedId.PersonId);
return service.DoSomethingWithResource(decryptedId.Id, personIdentity);
}
private class EncryptableId
{
public int Id { get; set; }
public int PersonId { get; set; }
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... meone-else