I have an MVC 5 project using Asp.Net Identity 2.0. I am also using a generic repository pattern. As part of the database schema I have fields for various tables which store the user id of the inserting/updating/deleting user. Therefore I would like to pass the user object, or user id at least to the generic repository to be used when modifying records.
However, as i was unable to access the identity directly in the repository class I am attempting to pass it on repository instantiation. It looks like this:
using System.Data.Entity;
using System.Threading.Tasks;
using System.Net;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using My.Models;
namespace My.Controllers
{
[Authorize]
public class FooController : MasterController
{
private IGenericRepositoryAsync<Topic> _repository;
public FooController()
{
//Point A
_repository = new GenericRepositoryAsync<Foo>(User.Identity);
}
public async Foo<ActionResult> Index()
{
//POINT B
//_repository = new GenericRepositoryAsync<Foo>(User.Identity);
return View(await _repository.GetAllAsync());
}
}
}
As an authorized user at "Point A" User.Identity is null, at //Point B it is not null but I don't want to have to put the repository initializer in every controller Action.
Your help and feedback is appreciated.
Web Api solution
You may create your on Authorize filter class and then add the userId into Request properties collection:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()) return;
base.OnAuthorization(actionContext);
Guid userId;
if (actionContext.RequestContext.Principal.Identity.IsAuthenticated
&& Guid.TryParse(actionContext.RequestContext.Principal.Identity.GetUserId(), out userId))
{
actionContext.Request.Properties.Add("userId", actionContext.RequestContext.Principal.Identity.GetUserId());
}
}
}
Once the class exists, you have to add this filter on Application Startup class (Global.asax web_start, Startup.cs) like this:
config.Filters.Add(new MyAuthorizeAttribute());
For Owin Startup.cs will be something like this:
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
config.Filters.Add(new MyAuthorizeAttribute());
}
Then, in your controller you will be able to get the userId jus doing:
Guid userId = (Guid) ActionContext.Request.Properties["userId"];
MVC Solution
For MVC use directly on Controller:
using Microsoft.AspNet.Identity;
...
User.Identity.GetUserId();
Or add a filter as in Web Api solution:
public override void OnAuthorization(AuthorizationContext filterContext)
{
...
Guid userId = filterContext.HttpContext.User.Identity.Name.GetUserId();
...
}