Added Authorization
This commit is contained in:
parent
04049f31f6
commit
e47d6488c2
15 changed files with 134 additions and 21 deletions
21
Lieb/Data/Constants.cs
Normal file
21
Lieb/Data/Constants.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
namespace Lieb.Data
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
|
||||
|
||||
public const string ClaimType = "Role";
|
||||
public static class Roles
|
||||
{
|
||||
public const string User = "User";
|
||||
public const string RaidLead = "RaidLead";
|
||||
public const string GuildLead = "GuildLead";
|
||||
public const string Admin = "Admin";
|
||||
|
||||
public static List<string> GetAllRoles()
|
||||
{
|
||||
return typeof(Roles).GetFields().Select(f => f.GetValue(f)).Cast<string>().ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,19 +7,27 @@ namespace Lieb.Data
|
|||
public static void Initialize(LiebContext context)
|
||||
{
|
||||
// Look for any students.
|
||||
if (context.Users.Any())
|
||||
if (context.LiebUsers.Any())
|
||||
{
|
||||
return; // DB has been seeded
|
||||
}
|
||||
|
||||
UserRole admin = new UserRole();
|
||||
admin.RoleName = Constants.Roles.Admin;
|
||||
UserRole guildLead = new UserRole();
|
||||
guildLead.RoleName = Constants.Roles.GuildLead;
|
||||
UserRole member = new UserRole();
|
||||
member.RoleName = Constants.Roles.User;
|
||||
|
||||
|
||||
var users = new LiebUser[]
|
||||
{
|
||||
new LiebUser{DiscordUserId=0, Name="Sarah",Birthday=DateTime.Parse("1992-01-15")},
|
||||
new LiebUser{DiscordUserId=0, Name="Lisa",Birthday=DateTime.Parse("1991-02-15")},
|
||||
new LiebUser{DiscordUserId=0, Name="Simon",Birthday=DateTime.Parse("2019-09-01")}
|
||||
new LiebUser{DiscordUserId=0, Name="Sarah",Birthday=DateTime.Parse("1992-01-15"), Roles=new List<UserRole>(){admin}},
|
||||
new LiebUser{DiscordUserId=1, Name="Lisa",Birthday=DateTime.Parse("1991-02-15"), Roles=new List<UserRole>(){guildLead} },
|
||||
new LiebUser{DiscordUserId=2, Name="Simon",Birthday=DateTime.Parse("2019-09-01"), Roles=new List<UserRole>(){member}}
|
||||
};
|
||||
|
||||
context.Users.AddRange(users);
|
||||
context.LiebUsers.AddRange(users);
|
||||
context.SaveChanges();
|
||||
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@ namespace Lieb.Data
|
|||
{
|
||||
}
|
||||
|
||||
public DbSet<LiebUser> Users { get; set; }
|
||||
public DbSet<LiebUser> LiebUsers { get; set; }
|
||||
public DbSet<UserRole> UserRoles { get; set; }
|
||||
public DbSet<GuildWars2Account> GuildWars2Account { get; set; }
|
||||
public DbSet<Equipped> Equipped { get; set; }
|
||||
public DbSet<GuildWars2Build> RaidRoles { get; set; }
|
||||
|
@ -27,6 +28,7 @@ namespace Lieb.Data
|
|||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<LiebUser>().ToTable("LiebUser");
|
||||
modelBuilder.Entity<UserRole>().ToTable("UserRole");
|
||||
modelBuilder.Entity<GuildWars2Account>().ToTable("GuildWars2Account");
|
||||
modelBuilder.Entity<Equipped>().ToTable("Equipped");
|
||||
modelBuilder.Entity<GuildWars2Build>().ToTable("GuildWars2Build");
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
using Lieb.Data;
|
||||
using Lieb.Models;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
|
@ -10,9 +13,12 @@ namespace Discord.OAuth2
|
|||
{
|
||||
internal class DiscordHandler : OAuthHandler<DiscordOptions>
|
||||
{
|
||||
public DiscordHandler(IOptionsMonitor<DiscordOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
|
||||
private readonly Lieb.Data.LiebContext _LiebDbcontext;
|
||||
|
||||
public DiscordHandler(IOptionsMonitor<DiscordOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, Lieb.Data.LiebContext context)
|
||||
: base(options, logger, encoder, clock)
|
||||
{
|
||||
_LiebDbcontext = context;
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
|
||||
|
@ -30,6 +36,16 @@ namespace Discord.OAuth2
|
|||
context.RunClaimActions();
|
||||
|
||||
await Events.CreatingTicket(context);
|
||||
|
||||
LiebUser? user = await _LiebDbcontext.LiebUsers.Include(u => u.Roles).FirstOrDefaultAsync(m => m.DiscordUserId == 1);
|
||||
if (user != null)
|
||||
{
|
||||
foreach (UserRole role in user.Roles)
|
||||
{
|
||||
context.Identity.AddClaim(new Claim(Constants.ClaimType, role.RoleName));
|
||||
}
|
||||
}
|
||||
|
||||
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace Discord.OAuth2
|
|||
TokenEndpoint = DiscordDefaults.TokenEndpoint;
|
||||
UserInformationEndpoint = DiscordDefaults.UserInformationEndpoint;
|
||||
Scope.Add("identify");
|
||||
//Scope.Add("guilds.members.read");
|
||||
|
||||
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id", ClaimValueTypes.UInteger64);
|
||||
ClaimActions.MapJsonKey(ClaimTypes.Name, "username", ClaimValueTypes.String);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
RandomEliteSpecialization = 4,
|
||||
}
|
||||
|
||||
public abstract class Raid
|
||||
public class Raid
|
||||
{
|
||||
public int RaidId { get; private set; }
|
||||
|
||||
|
|
|
@ -10,5 +10,6 @@ namespace Lieb.Models
|
|||
public string Pronouns { get; set; } = string.Empty;
|
||||
public DateTime? Birthday { get; set; }
|
||||
public ICollection<GuildWars2Account> GuildWars2Accounts { get; set; } = new List<GuildWars2Account>();
|
||||
public ICollection<UserRole> Roles { get; set; } = new List<UserRole>();
|
||||
}
|
||||
}
|
||||
|
|
9
Lieb/Models/UserRole.cs
Normal file
9
Lieb/Models/UserRole.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Lieb.Models
|
||||
{
|
||||
public class UserRole
|
||||
{
|
||||
public int UserRoleId { get; set; }
|
||||
|
||||
public string RoleName { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ namespace Lieb.Pages.Users
|
|||
return Page();
|
||||
}
|
||||
|
||||
_context.Users.Add(User);
|
||||
_context.LiebUsers.Add(User);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return RedirectToPage("./Index");
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace Lieb.Pages.Users
|
|||
return NotFound();
|
||||
}
|
||||
|
||||
User = await _context.Users.FirstOrDefaultAsync(m => m.LiebUserId == id);
|
||||
User = await _context.LiebUsers.FirstOrDefaultAsync(m => m.LiebUserId == id);
|
||||
|
||||
if (User == null)
|
||||
{
|
||||
|
@ -46,11 +46,11 @@ namespace Lieb.Pages.Users
|
|||
return NotFound();
|
||||
}
|
||||
|
||||
User = await _context.Users.FindAsync(id);
|
||||
User = await _context.LiebUsers.FindAsync(id);
|
||||
|
||||
if (User != null)
|
||||
{
|
||||
_context.Users.Remove(User);
|
||||
_context.LiebUsers.Remove(User);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Lieb.Pages.Users
|
|||
return NotFound();
|
||||
}
|
||||
|
||||
User = await _context.Users.FirstOrDefaultAsync(m => m.LiebUserId == id);
|
||||
User = await _context.LiebUsers.FirstOrDefaultAsync(m => m.LiebUserId == id);
|
||||
|
||||
if (User == null)
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Lieb.Pages.Users
|
|||
return NotFound();
|
||||
}
|
||||
|
||||
User = await _context.Users.FirstOrDefaultAsync(m => m.LiebUserId == id);
|
||||
User = await _context.LiebUsers.FirstOrDefaultAsync(m => m.LiebUserId == id);
|
||||
|
||||
if (User == null)
|
||||
{
|
||||
|
@ -72,7 +72,7 @@ namespace Lieb.Pages.Users
|
|||
|
||||
private bool UserExists(int id)
|
||||
{
|
||||
return _context.Users.Any(e => e.LiebUserId == id);
|
||||
return _context.LiebUsers.Any(e => e.LiebUserId == id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace Lieb.Pages.Users
|
|||
|
||||
public async Task OnGetAsync()
|
||||
{
|
||||
User = await _context.Users.ToListAsync();
|
||||
User = await _context.LiebUsers.ToListAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
using Discord.OAuth2;
|
||||
using Lieb.Data;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
|
@ -32,6 +29,15 @@ builder.Services.AddAuthentication(opt =>
|
|||
x.SaveTokens = true;
|
||||
});
|
||||
|
||||
builder.Services.AddAuthorization(options =>
|
||||
{
|
||||
foreach(string role in Constants.Roles.GetAllRoles())
|
||||
{
|
||||
options.AddPolicy(role, policy => policy.RequireClaim(Constants.ClaimType, role));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
|
@ -62,6 +68,7 @@ app.UseStaticFiles();
|
|||
|
||||
app.UseRouting();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
@inherits LayoutComponentBase
|
||||
@using System.Security.Claims
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<PageTitle>Lieb</PageTitle>
|
||||
|
||||
|
@ -20,9 +23,54 @@
|
|||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
</div>
|
||||
<AuthorizeView>
|
||||
<p>You can only see this if you are loged in</p>
|
||||
</AuthorizeView>
|
||||
<AuthorizeView Policy="Admin">
|
||||
<p>You can only see this if you satisfy the "Admin" policy.</p>
|
||||
</AuthorizeView>
|
||||
|
||||
|
||||
<article class="content px-4">
|
||||
@Body
|
||||
</article>
|
||||
<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>
|
||||
</main>
|
||||
</div>
|
||||
<p>@_authMessage</p>
|
||||
|
||||
@if (_claims.Count() > 0)
|
||||
{
|
||||
<ul>
|
||||
@foreach (var claim in _claims)
|
||||
{
|
||||
<li>@claim.Type: @claim.Value</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
|
||||
<p>@_surnameMessage</p>
|
||||
|
||||
@code {
|
||||
private string _authMessage;
|
||||
private string _surnameMessage;
|
||||
private IEnumerable<Claim> _claims = Enumerable.Empty<Claim>();
|
||||
|
||||
private async Task GetClaimsPrincipalData()
|
||||
{
|
||||
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
var user = authState.User;
|
||||
|
||||
if (user.Identity.IsAuthenticated)
|
||||
{
|
||||
_authMessage = $"{user.Identity.Name} is authenticated.";
|
||||
_claims = user.Claims;
|
||||
_surnameMessage =
|
||||
$"Surname: {user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value}";
|
||||
}
|
||||
else
|
||||
{
|
||||
_authMessage = "The user is NOT authenticated.";
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue