ASP.NET Core 6.0 - API Authorization
Download KH Authenticator

.NET MAUI App for Windows and Android
Online Registration and Authentication
No Password Or Email Address Required!
Certified Providers
KenHaggerty.Com Users Without Passwords Users With Passwords Users Without IdentityThis article describes restricting access to the member's image API endpoint to the user or an authorized administrator. I will assume you have downloaded the ASP.NET Core 6.0 - Users With Comments Project.
Users With Comments Project and Article Series
The ASP.NET Core 6.0 - Users With Comments Project (UWCP) implements public member profiles and a moderated comment workflow from user submission to admin publication. I started with the ASP.NET Core 6.0 - Users With Device 2FA Project (UWD2FAP) which implements WebAuthn, also known as FIDO2, instead of authenticator apps. The latest version of the UWCP is published at Preview. KenHaggerty. Com. I encourage you to register and submit a comment. Details, screenshots, and related articles can be found at ASP.NET Core 6.0 - Users With Comments Project. The details page includes the version change log.
- ASP.NET Core 6.0 - Users With Comments
- ASP.NET Core 6.0 - API Implementation
- ASP.NET Core 6.0 - API Authorization
- ASP.NET Core 6.0 - Member Profile
- ASP.NET Core 6.0 - Profile Image Control
- ASP.NET Core 6.0 - Comments Workflow
- ASP.NET Core 6.0 - Filtered Comments
- ASP.NET Core 6.0 - Member Listings
- ASP.NET Core 6.0 - Lazy Load On Scroll
Visual Studio 2022 (VS 2022) is required to develop .NET 6 and ASP.NET Core 6.0 applications. .NET 6 and ASP.NET Core 6.0 are Long Term Support (LTS) releases and will be supported until November 08, 2024. .NET 5 is a Current release and will be supported until May 08, 2022. .NET 3.1 is a LTS release and will be supported until December 3, 2022. See .NET and .NET Core release lifecycle.
I wanted to encourage users to use a profile image. I had already implemented Croppie to crop and resize a file image before it is uploaded and stored as a Data URL. I developed a Profile Image Control which adds options to use a webcam snapshot, or a stock image stored on the server.
The Profile Image Control implements the ProfileImageControler and a partial view. The partial implements the JavaScript that calls the ProfileImageControler. The _ProfileImagePostPartial is displayed on the Manage Account > Picture and the Admin > AppUsers > Edit page.
<partial name="_ProfileImagePostPartial" />
Many API endpoints need restricted access. Some need access by the user and/or an authorized administrator. The UWCP implements Authorization policies. I added MemberProfile and Comments Claims.
The ProfileImageControler's Get method has an appUserId parameter with a default value = 0. If the appUserId is not set, the current user is granted read write access to their picture. The Admin > Edit page sets the appUserId to the edit user's id. The ProfileImageControler injects the AuthorizationService to authorize the MemberProfilesRead and MemberProfilesWrite policies for the admin user.
private readonly IUserService _userService; private readonly IAuthorizationService _authorizationService; private readonly IWebHostEnvironment _environment; public ProfileImageController( IUserService userService, IAuthorizationService authorizationService, IWebHostEnvironment environment) { _userService = userService; _environment = environment; _authorizationService = authorizationService; } [HttpGet] [Route("Get")] public async Task<JsonResult> GetAsync(int appUserId = 0) { if (!User.Identity?.IsAuthenticated ?? false) return new JsonResult(new { Status = "Failed", Errors = "Not Authenticated", Id = appUserId }); var currentAppUserId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)); var useStaffStock = User != null && (User.Claims.Any(c => c.Type == AppClaimTypes.Comment && c.Value == AppClaimValues.Write) || User.Claims.Any(c => c.Type == AppClaimTypes.Super)); var canUpdate = false; if (appUserId == 0) { appUserId = currentAppUserId; canUpdate = true; } else { if (User == null || !(await _authorizationService.AuthorizeAsync(User, AuthorizationPolicies.MemberProfilesRead)).Succeeded) return new JsonResult(new { Status = "Failed", Errors = "Not Authorized", Id = currentAppUserId }); var userClaims = await _userService.GetAppUserClaimsAsync(appUserId).ConfigureAwait(false); useStaffStock = userClaims.Any(c => c.Type == AppClaimTypes.Comment && c.Value == AppClaimValues.Write) || userClaims.Any(c => c.Type == AppClaimTypes.Super); canUpdate = User != null && (await _authorizationService.AuthorizeAsync(User, AuthorizationPolicies.MemberProfilesWrite)).Succeeded; } var currentImageString = await _userService.GetMemberProfileImageStringAsync(appUserId).ConfigureAwait(false); if (string.IsNullOrEmpty(currentImageString)) currentImageString = AppSettings.AnonymousImage; else if (!currentImageString.StartsWith("data:image/")) { if (!System.IO.File.Exists(Path.Combine(_environment.WebRootPath, currentImageString[1..]))) currentImageString = AppSettings.NotFoundImage; } ProfileImageInputModel profileImageInputModel = new(); profileImageInputModel.Status = "Success"; profileImageInputModel.CanUpdate = canUpdate; profileImageInputModel.CurrentImageString = currentImageString; profileImageInputModel.ImageTagWidth = AppSettings.MemberImageWidth; profileImageInputModel.ShowRemove = currentImageString != AppSettings.AnonymousImage; profileImageInputModel.StockEnabled = AppSettings.ProfileImageStockEnabled; profileImageInputModel.CropEnabled = AppSettings.ProfileImageCropEnabled; profileImageInputModel.CaptureEnabled = AppSettings.ProfileImageCaptureEnabled; if (AppSettings.ProfileImageStockEnabled) { var directoryPath = Path.Combine(_environment.WebRootPath, AppSettings.ProfileImageStockFolder[1..]); if (useStaffStock) directoryPath = Path.Combine(_environment.WebRootPath, AppSettings.ProfileImageStaffFolder[1..]); // Add image file name and relative path to StockImages. string[] fileNamePaths = Directory.GetFiles(directoryPath); foreach (string fileNamePath in fileNamePaths) { var fileName = Path.GetFileName(fileNamePath); var relativePath = Path.Combine(useStaffStock ? AppSettings.ProfileImageStaffFolder : AppSettings.ProfileImageStockFolder, fileName); profileImageInputModel.StockImages.Add(fileName, relativePath); } } return new JsonResult(profileImageInputModel); }
Comments(0)