Reputation: 83
I'm working on a Blazor Wasm web app. I have a Web API for retrieving and editing the data. Now I want to add authorization to my app but I keep confusing myself.
I want to use a blog with posts and their comments as an example.
My database consists of multiple posts. Each post has information like title, text, author and createdDateTime
. Also: posts have multiple comments. Each comment has its text, author, createdDateTime
and it can be marked private, meaning only registered users are able to see the comment.
So now the interesting part:
blog posts can only be accessed through a link, that needs to be shared, e.g: fancyblog.com/blogs/123-abc-456
(using a guid). The author is able to customize what fields are viewable through the link by public: e.g. (title and text) or (title, text and createdAtDate
)
If an anonymous user accesses a blog post, only the selected parts shall be shown. And also only non-private comments, here also: only the chosen values (e.g. only text).
If a logged-in user accesses a blog post, he shall be able to view everything, including the private comments.
Now to my question: would I still be using the [Authorize]
attribute (Web API) and the <AuthorizeView>&<Authorized>
components (Razor page) for only displaying viewable data?
I know that I have to restrict access within the Web API, as the wasm can be manipulated. I would love to do something like this:
[AllowAnonymous]
[HttpGet("{id}")]
public async Task<ActionResult<BlogDTO> GetBlog(Guid id)
{
Blog? blog = FindBlogForId(_context, id);
if(blog == null)
return NotFound();
return new BlogDTO
{
Title = GetTitle(blog), //Return null if policy is missing
Text = GetText(blog),
AuthorName = GetAuthorName(blog),
CreatedAtDate = GetCreatedAtDate(blog),
}
}
[Authorize(Policy="SeeTitle")]
public string? GetTitle(Blog blog)
{
return blog.Title; //How to return null if policy is missing?
}
And then in the Blazor app:
@*...*@
<AuthorizeView>
<Authorized>
<h1>@blog.Title</h1>
</Authorized>
</AuthorizeView>
<AuthorizeView>
<Authorized>
<p>@blog.Text</p>
</Authorized>
</AuthorizeView>
@*...*@
@code
{
[Parameter]
public Guid BlogId { get; set; }
private BlogDTO _blog;
protected override async Task OnInitializedAsync()
{
_blog = await Http.GetFromJsonAsync<BlogDTO>($"api/Blogs/{BlogId}");
}
}
Now I see multiple flaws:
[Authorize]
on the GetTitle
method apparently has no effect<AuthorizeViews>
ApplicationUser
when GetBlog
is accessed by unauthorized user. But this seems to not be a big deal.Am I mixing things up? Probably I could do all the checks on the database combined with a check on User.Identity.IsAuthenticated
, but is this really it? It does not feel like best practice - completely ignoring the attributes....
Upvotes: 0
Views: 34
Reputation: 1637
Based on the security policy , https://learn.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-8.0#authorization , the data is usually protected in WebApi , so checks on the database combined with a check on User.Identity.IsAuthenticated
is not a bad choice , as it can keep the security logic clear , and the maintenance simple .
As to the Authorize
attribute , the attribute on controller or action verify whether user can access the method but not the data . In your project please check if the policy is registered correctly in program .
You could try a Role-Based Authorization in Blazor AuthorizeView component , https://learn.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-8.0#authorizeview-component , it is easier to define roles with different permissions to control the Viewdata to be displayed.
Upvotes: 0