Search code examples
apiauthenticationrazorblazorauthorization

Blazor Secure Api


I am developing an Application in Microsoft Blazor. I have secured all the UI Pages using a custom AuthenticationStateProvider class which searches for a cookie on the browser.

The by restricting the @Body on the MainLayout.razor every page is secured and not readable when the user is not autorized.

   <div class="page">
       <Sidebar />

        <div class="main">
            <Header />

            <article class="content px-4">
                <AuthorizeView>
                    <NotAuthorized>
                        <div class="row">
                            <div class="col-md-4">
                                <p>Please sign in to use the Platform...</p>
                            </div>
                        </div>
                    </NotAuthorized>
                    <Authorized>
                       @Body
                    </Authorized>
                </AuthorizeView>
            </article>

        </div>
    </div>

The issue is that the ./api endpoint is still accessible for not authorized users as the controllers are still active.

    [Route("api/User")]
    [ApiController]
    public class Controller_User : ControllerBase
    {
        private readonly Interface_User _IUser;

        public Controller_User(Interface_User iUser)
        {
            _IUser = iUser;
        }

        [HttpGet, Route("/api/user/view")]
        public async Task<List<User>> GetUsers()
        {
            try { return await Task.FromResult(_IUser.GetUsers()); }
            catch { throw; }
        }
    }

Any ideas how we can secure all ./api urls at once like the razor pages?


Solution

  • Example using inheritance to apply Authorization to controllers.

    Two abstract controllers

    [Authorize]  
    public abstract class AuthorizedController: Controller {}
    
    [Authorize(Policy = "AdminOnly")]
    public abstract class AdminOnlyAuthorizedController: Controller {}
    

    And then some implementations

    public sealed class WeatherForecastController: AuthorizedController {  
    //....
    }
    
    public sealed class WeatherLocationController: AuthorizedController {  
    //....
    
    public class MyAdminController: AdminOnlyAuthorizedController {  
    //....
    }