Tworzę sobię backend w ASP.Net z autoryzacją. Do zrobienia tego skorzystałem z tego - https://jasonwatmore.com/post/2019/10/14/aspnet-core-3-simple-api-for-authentication-registration-and-user-management#running-react
Zrobiłem sobie endpoint do dodawania zdjęcia na serwer dla konkretnego usera:
[Authorize]
[HttpPost("{username}/photos/")]
public IActionResult AddPhoto(String username, [FromForm]IFormFile photo)
{
//add img to static folder
var wwww_root = _webHostEnvironment.WebRootPath;
var path = @"\profiles\" + username + @"\profile_photos\";
var upload_path = wwww_root + path;
var pathForFile = upload_path + photo.FileName;
try
{
using (FileStream fileStream = System.IO.File.Create(pathForFile))
{
photo.CopyTo(fileStream);
fileStream.Flush();
}
}
catch(DirectoryNotFoundException e)
{
return NotFound("This username does not exists");
}
var pathOnServer = "http://" + Request.Host.Value + path + photo.FileName;
var photoImage = _profileService.AddPhoto(username, pathOnServer);
return Ok();
}
i to działa, ale chciałbym by dla podanego username był wymagany Bearer Token, bo w tym wypadku owszej jest wymagany bearer token, ale działa dla wszystkich tokenów. By jaśniej zoobrazować sytuację:
Mam endpoint - http://localhost:4000/profiles/{username}/photos/
jeśli jako username podam np. admin chciałbym by był wymagany token przypisany właśnie dla admina, a tokeny innych użytkowników były odrzucane.
W podanym linku znalazłem konfigurację dla autentyfikacji
// configure jwt authentication
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();
var userId = int.Parse(context.Principal.Identity.Name);
var user = userService.GetById(userId);
if (user == null)
{
// return unauthorized if user no longer exists
context.Fail("Unauthorized");
}
return Task.CompletedTask;
}
};
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
i metodę w kontrolerze do wywołania autentykacji
[AllowAnonymous]
[HttpPost("authenticate")]
public IActionResult Authenticate([FromBody]AuthenticateModel model)
{
var user = _userService.Authenticate(model.Username, model.Password);
if (user == null)
return BadRequest(new { message = "Username or password is incorrect" });
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
// return basic user info and authentication token
return Ok(new
{
Id = user.Id,
Username = user.Username,
FirstName = user.FirstName,
LastName = user.LastName,
Token = tokenString
});
}
ale nie potrafię tego przełożyć na rozwiązanie mojego problemu. Bardzo proszę o wskazówki jak to moge zrobić.