AspNetCore.Authorization.Permissions icon indicating copy to clipboard operation
AspNetCore.Authorization.Permissions copied to clipboard

Create RolePermissions using EF

Open OmarAljoundi opened this issue 1 year ago • 1 comments

Hello @mgernand Thank you for your great effort in publishing such a great library.

I was trying to add role permissions in the table RolePermissions which accepts a role Id and permission Id, so far this is what I come up with

[Route("api/[controller]")]
[ApiController]
public class RolePermissionsController(ILogger<RolePermissionsController> _logger,
    PermissionStore<IdentityPermission, IdentityRole> _rolePermissions) : ControllerBase
{

    [HttpPost("Post")]
    public async Task<IActionResult> CreateRolePermission([FromQuery] string RoleId, [FromQuery] string PermissionId)
    {
        _logger.LogInformation("Create Role Permission called");
        var permission = await _rolePermissions.FindByIdAsync(PermissionId,default);
        if (permission is not null)
        {
           await _rolePermissions.AddToRoleAsync(permission, RoleId.Normalize(), default);

        }

        return Ok();
    }
}

but it keeps giving me ### Unable to resolve service for type 'MadEyeMatt.AspNetCore.Identity.Permissions.EntityFrameworkCore.PermissionStore

Altho, the AddPermissionsEntityFrameworkStores<ApplicationDbContext>(); should handle registering this service.

Here is my program.cs


using Core.Identity.WepApi;
using Core.Identity.WepApi.Modal;
using MadEyeMatt.AspNetCore.Authorization.Permissions;
using MadEyeMatt.AspNetCore.Identity.Permissions;
using MadEyeMatt.AspNetCore.Identity.Permissions.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.IdentityModel.Tokens.Jwt;
using System.Text;

var builder = WebApplication.CreateBuilder(args);


builder.Services.AddControllers();
builder.Services.AddAuthorization();
builder.Services.AddPermissionsAuthorization();

builder.Services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
    options.User.AllowedUserNameCharacters += " ")
           .AddEntityFrameworkStores<ApplicationDbContext>()
           .AddDefaultTokenProviders();


builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        In = ParameterLocation.Cookie,
        Description = "Please enter 'Bearer [jwt]'",
        Name = "Authorization",
        Type = SecuritySchemeType.ApiKey
    });

    var scheme = new OpenApiSecurityScheme
    {
        Reference = new OpenApiReference
        {
            Type = ReferenceType.SecurityScheme,
            Id = "Bearer"
        }
    };

    options.AddSecurityRequirement(new OpenApiSecurityRequirement { { scheme, Array.Empty<string>() } });
});

using var loggerFactory = LoggerFactory.Create(b => b.SetMinimumLevel(LogLevel.Trace).AddConsole());

var secret = builder.Configuration["JWT:Secret"] ?? throw new InvalidOperationException("Secret not configured");

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.SaveToken = true;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = builder.Configuration["JWT:ValidIssuer"],
        ValidAudience = builder.Configuration["JWT:ValidAudience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)),
        ClockSkew = new TimeSpan(0, 0, 5)
    };
    options.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            var accessToken = context.Request.Cookies[PresentingOptions.AccessTokenKey]; // Replace 'YourCookieName' with the actual name of your cookie
            if (!string.IsNullOrEmpty(accessToken))
            {
                context.Request.Headers.Append("Authorization", $"Bearer {accessToken}");
            }
            return Task.CompletedTask;
        },
        OnChallenge = ctx => LogAttempt(ctx.Request.Headers, "OnChallenge"),
        OnTokenValidated = ctx => LogAttempt(ctx.Request.Headers, "OnTokenValidated")
    };
});


builder.Services
    .AddDbContext<ApplicationDbContext>(options =>
    {
        options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
    })
    .AddPermissionsIdentityCore<IdentityUser, IdentityRole, IdentityPermission>()
    .AddDefaultUI()
    .AddDefaultTokenProviders()
    .AddPermissionClaimsProvider()
    .AddUserManager<AspNetUserManager<IdentityUser>>()
    .AddRoleManager<AspNetRoleManager<IdentityRole>>()
    .AddPermissionManager<AspNetPermissionManager<IdentityPermission>>()
    .AddPermissionsEntityFrameworkStores<ApplicationDbContext>();
    

const string policy = "defaultPolicy";

builder.Services.AddCors(options =>
{
    options.AddPolicy(policy,
                      p =>
                      {
                          p.AllowAnyHeader();
                          p.AllowAnyMethod();
                          p.AllowAnyHeader();
                          p.AllowAnyOrigin();
                      });
});

var app = builder.Build();

//PopulateDb();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseCors(policy);

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

Task LogAttempt(IHeaderDictionary headers, string eventType)
{
    var logger = loggerFactory.CreateLogger<Program>();

    var authorizationHeader = headers["Authorization"].FirstOrDefault();

    if (authorizationHeader is null)
        logger.LogInformation($"{eventType}. JWT not present");
    else
    {
        string jwtString = authorizationHeader.Substring("Bearer ".Length);

        var jwt = new JwtSecurityToken(jwtString);

        logger.LogInformation($"{eventType}. Expiration: {jwt.ValidTo.ToLongTimeString()}. System time: {DateTime.UtcNow.ToLongTimeString()}");
    }

    return Task.CompletedTask;
}


Any thoughts?

OmarAljoundi avatar Jan 26 '24 22:01 OmarAljoundi