2

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.

painiyff
  • 2,519
  • 6
  • 21
  • 29

1 Answers1

2

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
    }
}
adem caglin
  • 22,700
  • 10
  • 58
  • 78
  • Doesn't the Session.Set only accept byte array, not object? – painiyff May 12 '16 at 19:32
  • Never mind, I converted object to JSON string instead: [linky](http://stackoverflow.com/questions/35993415/asp-net-5-core-how-to-store-objects-in-session-cache-isession) – painiyff May 12 '16 at 19:38