painiyff
painiyff

Reputation: 2709

How to persist policy authorization results for users in ASP.NET Core, MVC 6?

Currently I have a simple custom policy handler that looks like so:

protected override void Handle(AuthorizationContext context, UserPolicyRequirement requirement)
{
    // authorize user against policy requirements
    if (_authorizationTask.AuthorizeUserAgainstPolicy(context.User, requirement))
    {
        // User passed policy req's 
        context.Succeed(requirement);
    }
}

Problem is, this authorization step takes a long time to execute, but this is required in many different areas of the website. Is there any readily available mechanisms to save/cache the results of this policy authorization so that I only need to do this once per session?

I am currently using Windows Authentication, if that helps.

Upvotes: 2

Views: 962

Answers (1)

adem caglin
adem caglin

Reputation: 24083

If per session way does not cause any problem, you can use Session to store user data. Simple implementation is something like below:

First you need a service to get user data from any store

public interface IGetUserDataService
{
    <type> GetUserData();
}

I assume that there is Session configuration(see) and IGetUserDataService implementation.

Then you need to create a middleware to handle Session

public class SessionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IGetUserDataService _getUserDataService;

    public SessionMiddleware(RequestDelegate next, IGetUserDataService getUserDataService)
    {
        _next = next;
        _getUserDataService = getUserDataService;
    }

    public async Task Invoke(HttpContext context)
    {
        //user data is obtained only once  then is stored in Session
        if (context.Session.Get("UserData") == null)
        {
            context.Session.Set("UserData", getUserDataService.GetData());
        }
        await _next.Invoke(context);
    }
}

//In Startup.cs
app.UseMiddleware<SessionMiddleware>();

Finally get and use session data in handler

public class YourHandler : AuthorizationHandler<YourRequirement>
{
    private readonly IHttpContextAccessor _accessor;
    public YourHandler(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }
    protected override void Handle(AuthorizationContext context, PermissionRequirement requirement)
    {
        var userData =(<type>)_accessor.HttpContext.Session.Get("UserData");
        // check
    }
}

Upvotes: 2

Related Questions