Skip to content

Commit

Permalink
Updated Example1
Browse files Browse the repository at this point in the history
  • Loading branch information
JonPSmith committed Jul 3, 2021
1 parent 092f374 commit 3130c8e
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 92 deletions.
6 changes: 3 additions & 3 deletions AuthPermissions/PermissionsCode/PermissionChecks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ public static class PermissionChecks
/// <param name="user"></param>
/// <param name="permission"></param>
/// <returns></returns>
public static bool UserHasThisPermission<TEnumPermissions>(this ClaimsPrincipal user, TEnumPermissions permission)
public static bool HasPermission<TEnumPermissions>(this ClaimsPrincipal user, TEnumPermissions permission)
where TEnumPermissions : Enum
{
var permissionClaim =
user?.Claims.SingleOrDefault(x => x.Type == PermissionConstants.PackedPermissionClaimType);
return permissionClaim?.Value.UserHasThisPermission(permission) == true;
return permissionClaim?.Value.HasPermission(permission) == true;
}

/// <summary>
Expand All @@ -46,7 +46,7 @@ public static bool ThisPermissionIsAllowed(this Type enumPermissionType, string

//-------------------------------------------------------
//private methods
private static bool UserHasThisPermission<TEnumPermissions>(this string packedPermissions, TEnumPermissions permissionToCheck)
private static bool HasPermission<TEnumPermissions>(this string packedPermissions, TEnumPermissions permissionToCheck)
where TEnumPermissions : Enum
{
var permissionAsChar = (char)Convert.ChangeType(permissionToCheck, typeof(char));
Expand Down
15 changes: 9 additions & 6 deletions Example1.RazorPages.IndividualAccounts/Model/AppSummary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ namespace Example1.RazorPages.IndividualAccounts.Model
public class AppSummary
{
public string Application { get; } = "ASP.NET Core, Razor Pages";
public string AuthenticationType { get; } = "Cookies";
public string Users { get; } = "ASP.NET Core's individual accounts";
public string Roles { get; } = "Handled by AuthPermissions";
public string DataKey { get; } = "ASP.NET Core, Razor Pages";
public string Databases { get; } = "ASP.NET Core, Razor Pages";
public string Note { get; } = "Also has ASP.NET Core's individual account roles, to show how AuThPermissions is uses role differently";
public string AuthorizationProvider { get; } = "ASP.NET Core's individual accounts";
public string CookieOrToken { get; } = "Cookie";
public string DataKey { get; } = "- not used -";
public string[] Databases { get; } = new []
{
"Individual accounts: InMemoryDatabase",
"AuthPermissions: In-memory database (uses SQLite in-memory)"
};
public string Note { get; } = "This is a basic example of AuthPermissions Roles and permissions.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
{
public IActionResult OnGet()
{
if (!User.UserHasThisPermission(Example1Permissions.Permission2))
return Challenge();
if (!User.HasPermission(Example1Permissions.Permission2))
return Challenge();

return Page();
return Page();
}
}
</code></pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class NeedsPermission2Model : PageModel
{
public IActionResult OnGet()
{
if (!User.UserHasThisPermission(Example1Permissions.Permission2))
if (!User.HasPermission(Example1Permissions.Permission2))
return Challenge();

return Page();
Expand Down
162 changes: 99 additions & 63 deletions Example1.RazorPages.IndividualAccounts/Pages/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@

<h3>Welcome to example 1 of using the AuthPermissions library</h3>
<p>
This example shows how to manage authorization in an <strong>ASP.NET Core razor pages</strong> web application
use both the in-built ASP.NET Core authorization features and then using the AuthPermissions library.
<br/>
See <a href="https://docs.microsoft.com/en-us/aspnet/core/security/authorization/secure-data">
ASP.NET Core documentation on building razor page web app individual accounts authorization
</a>.
This ASP.NET Core razor pages web site provides an example of <strong>
how the AuthPermissions library handles authorization
</strong>,
that is controlling what pages and methods a user can access.
</p>
<h4>Application summary</h4>
<ul>
<li><strong>@nameof(AppSummary.Application)</strong>:&nbsp;@Model.AppSummary.Application</li>
<li><strong>@nameof(AppSummary.AuthenticationType)</strong>:&nbsp;@Model.AppSummary.AuthenticationType</li>
<li><strong>@nameof(AppSummary.Users)</strong>:&nbsp;@Model.AppSummary.Users</li>
<li><strong>@nameof(AppSummary.Roles)</strong>:&nbsp;@Model.AppSummary.Roles</li>
<li><strong>@nameof(AppSummary.AuthorizationProvider)</strong>:&nbsp;@Model.AppSummary.AuthorizationProvider</li>
<li><strong>@nameof(AppSummary.CookieOrToken)</strong>:&nbsp;@Model.AppSummary.CookieOrToken</li>
<li><strong>@nameof(AppSummary.DataKey)</strong>:&nbsp;@Model.AppSummary.DataKey</li>
<li><strong>@nameof(AppSummary.Databases)</strong>:&nbsp;@Model.AppSummary.Databases</li>
<li>
<strong>@nameof(AppSummary.Databases)</strong>:&nbsp;
<ul>
@foreach (var database in Model.AppSummary.Databases)
{
<li>@database</li>
}
</ul>
</li>
@if (@Model.AppSummary.Note != null)
{
<li><strong>@nameof(AppSummary.Note)</strong>:&nbsp;@Model.AppSummary.Note</li>
Expand All @@ -39,63 +44,94 @@
}
</ul>

<br/>
<br />

<p><strong>Click the links to see what happens</strong></p>

<h3>AuthPermissions authorization approaches</h3>
<p>
In summary, AuthPermissions roles are contain a series of <i>Permissions</i>.
This means that a user can have roles, but if you want to what change what a
role does, then you don't need to edit your code - you just change the Role's
permissions in the AuthPermissions database.
</p>
<p>
In this example:
</p>
<ul>
<li>The Trainee user has no AuthP roles, so they can't access the two pages below</li>
<li>The Staff user, has a Role1, which only has Permission1, so they can't open the second link</li>
<li>The Manager user, has a Role2, which has Permission1 and Permission2, so they open both links</li>
</ul>
<table class="table">
<thead>
<tr>
<th>Link to razor page</th>
<th>Access</th>
<th>Auth type</th>
</tr>
<tr>
<th>Link to razor page</th>
<th>Access</th>
<th>Auth type</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthBuiltIn/Public">Public page</a>
</td>
<td>Anyone</td>
<td>default</td>
</tr>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthBuiltIn/LoggedInConfigure">Logged in page</a>
</td>
<td>Must be logged in</td>
<td>
<code>Configure</code>
</td>
</tr>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthBuiltIn/LoggedInAuthorize">Logged in page</a>
</td>
<td>Must be logged in</td>
<td>
<code>[Authorize]</code>
</td>
</tr>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthBuiltIn/LoggedInUser">Logged in page</a>
</td>
<td>Must be logged in</td>
<td>Test <code>User</code> instance</td>
</tr>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthPermissions/NeedsPermission1">Logged in page</a>
</td>
<td>User must have Permission1</td>
<td><code>[HasPermission(Example1Permissions.Permission1)]</code></td>
</tr>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthPermissions/NeedsPermission2">Logged in page</a>
</td>
<td>User must have Permission2</td>
<td><code>User.UserHasThisPermission(Example1Permissions.Permission2)</code></td>
</tr>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthPermissions/NeedsPermission1">Logged in page</a>
</td>
<td>User must have Permission1</td>
<td>
Add <code>[HasPermission(Example1Permissions.Permission1)]</code> to the Razor Page method
</td>
</tr>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthPermissions/NeedsPermission2">Logged in page</a>
</td>
<td>User must have Permission2</td>
<td>
Test the user with <code>User.HasPermission(Example1Permissions.Permission2)</code>
<hr />
The <code>HasPermission</code> method is useful in Blazor and razor pages
</td>
</tr>
</tbody>
</table>

<h3>The normal ASP.NET Core authorization approaches</h3>
<p>Compare this with ASP.NET Core authorization approaches</p>
<table class="table">
<thead>
<tr>
<th>Link to razor page</th>
<th>Access</th>
<th>Auth type</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthBuiltIn/Public">Public page</a>
</td>
<td>Anyone</td>
<td>Same with with AuthPermissions</td>
</tr>
<tr>
<td>
<a class="nav-link text-primary" asp-area="" asp-page="/AuthBuiltIn/LoggedInAuthorize">Logged in page</a>
</td>
<td>Must be logged in</td>
<td>
Using <code>[Authorize]</code> attribute on the Razor Page method.
<hr />
Same with with AuthPermissions.
</td>
</tr>
<tr>
<td>
Not shown
</td>
<td>Must have individual accounts' "Manager" role</td>
<td>
Using <code>[Authorize(Roles = "Manager"]</code> attribute on the Razor Page method
<hr/>
DIFFERENT in AuthPermissions. No need to edit/redeploy your app if Role change
</td>
</tr>
</table>
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ namespace Example1.RazorPages.IndividualAccounts.PermissionsCode
public static class AppAuthSetupData
{
public const string ListOfRolesWithPermissions = @"Role1: Permission1
Role2: Permission2
Role2: Permission1, Permission2
SuperRole: AccessAll";

public static List<DefineUserWithRolesTenant> UsersRolesDefinition = new List<DefineUserWithRolesTenant>
{
new DefineUserWithRolesTenant("Permission1@g1.com", null, "Role1"),
new DefineUserWithRolesTenant("Permission2@g1.com", null, "Role2"),
new DefineUserWithRolesTenant("Staff@g1.com", null, "Role1"),
new DefineUserWithRolesTenant("Mananger@g1.com", null, "Role2"),
new DefineUserWithRolesTenant( "[email protected]", null, "SuperRole"),
};
}
Expand Down
21 changes: 12 additions & 9 deletions Example1.RazorPages.IndividualAccounts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,27 @@
This project contains a example of using the AuthPermissions.AspNetCore library in ASP.NET Core razor page web app with user data provided by the individual accounts approach. This is one of the simplest approaches using:

- **Application**: ASP.NET Core, Razor Pages
- **AuthenticationType**: Cookie
- **Users**: ASP.NET Core's individual accounts
- **Roles**: Handled by AuthPermissions
- **AuthorizationProvider**: ASP.NET Core's individual accounts
- **CookieOrToken**: Cookie
- **DataKey**: not used
- **Database type**: SQLite in-memory
- **Databases**: Two databases
- ASP.NET Core ApplicationDbContext for individual users.
- AuthPermissionsDbContext for AuthPermissions features.
- Individual accounts: InMemoryDatabase:
- AuthPermissions: In-memory database (uses SQLite in-memory).

The ASP.NET Core code comes comes from the [ASP.NET Core documentation on building razor page web app individual accounts authorization](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/secure-data), but the handling of the visibilty of the contact manager features are handled by the AuthPermissions.AspNetCore library.

The AuthPermissions.AspNetCore code/features used in this example

- Mapping the user's Roles to Permissions (read this doc !!! link needed !!!).
- Adding the AuthPermissions into your ASP.NET Core application.
- Bulk loading AuthPermissions Roles and Users.
- Mapping the user's Roles to Permissions.
- Authorization in razor pages via the `[HasPermission(<enum permission>)]` attribute on the `PageModel` class.
- Authorization in razor pages via the `IsAuthorized(<enum permission>)` method in the razor page itself.
- Authorization in razor pages via the `User.HasPermission(<enum permission>)` method.
- Add SuperUser on startup feature.
- Admin page to alter the permissions in each role.

This article (!!! LINK !!!) details how this example was built, and how it works.

NOTE: This example does not include the admin pages for

*NOTE: [This article](https://blog.francium.tech/asp-net-core-basic-authentication-authorization-in-razor-pages-with-postgresql-b1f2888b21d0) provides a good overview of the standard ASP.NET Core authorization approaches.*

1 change: 0 additions & 1 deletion Example1.RazorPages.IndividualAccounts/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using AuthPermissions.AspNetCore.Services;
using Example1.RazorPages.IndividualAccounts.Data;
using Example1.RazorPages.IndividualAccounts.PermissionsCode;
using Microsoft.EntityFrameworkCore.InMemory;
using ExamplesCommonCode.DemoSetupCode;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
Expand Down
2 changes: 1 addition & 1 deletion Example1.RazorPages.IndividualAccounts/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
"Email": "[email protected]",
"Password": "[email protected]"
},
"DemoUsers": "NoPermissions@g1.com,Permission1@g1.com,Permission2@g1.com"
"DemoUsers": "Trainee@g1.com,Staff@g1.com,Mananger@g1.com"
}
2 changes: 1 addition & 1 deletion ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

## Code still needed

All done.
- Implment the Hierarchical Tenant shop in Example4

## Documanation etc. still needed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void TestUnpackPermissionsFromString(TestEnum enumToTest, bool isAllowed)
}, "TestAuthentication"));

//ATTEMPT
var result = user.UserHasThisPermission(enumToTest);
var result = user.HasPermission(enumToTest);

//VERIFY
result.ShouldEqual(isAllowed);
Expand Down

0 comments on commit 3130c8e

Please sign in to comment.