在MVC 5控制器初始化程序中,Identity 2.0用户标识为空

时间:2014-09-18 08:51:55

标签: c# asp.net asp.net-mvc-5 asp.net-identity-2

我有一个使用Asp.Net Identity 2.0的MVC 5项目。我也在使用通用的存储库模式。作为数据库模式的一部分,我有各种表的字段,用于存储插入/更新/删除用户的用户ID。因此,我想将用户对象或用户id至少传递给修改记录时要使用的通用存储库。

但是,由于我无法直接在存储库类中访问该标识,因此我尝试在存储库实例化时传递它。它看起来像这样:

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());
        }
    }
}

作为“Point A”的授权用户,User.Identity为null,在// B点,它不是null,但我不想将存储库初始化程序放在每个控制器Action中。

感谢您的帮助和反馈。

2 个答案:

答案 0 :(得分:3)

Web Api解决方案

您可以在Authorize过滤器类上创建,然后将 userId 添加到Request属性集合中:

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());
        }
    }
}

一旦该类存在,您必须在Application Startup类(Global.asax web_start,Startup.cs)上添加此过滤器,如下所示:

config.Filters.Add(new MyAuthorizeAttribute());

对于Owin Startup.cs将是这样的:

public void Configuration(IAppBuilder app)
{
    ConfigureOAuth(app);

    HttpConfiguration config = new HttpConfiguration();
    WebApiConfig.Register(config);
    config.Filters.Add(new MyAuthorizeAttribute());
}

然后,在您的控制器中,您将能够获得 userId jus:

Guid userId = (Guid) ActionContext.Request.Properties["userId"];

MVC解决方案

直接在Controller上使用MVC:

using Microsoft.AspNet.Identity;

...

User.Identity.GetUserId();

或者在Web Api解决方案中添加过滤器:

public override void OnAuthorization(AuthorizationContext filterContext)
{
    ...
    Guid userId = filterContext.HttpContext.User.Identity.Name.GetUserId();
    ...
}

答案 1 :(得分:-1)

MVC的细微澄清,GetUserId应该从OnAuthentication()内部调用,用户ID在构造函数中尚不可用:

protected override void OnAuthentication(System.Web.Mvc.Filters.AuthenticationContext filterContext) {
      Repo = new ReposWrapper();

      try {
         Repo.CurrentUserId = User.Identity.GetUserId();
      } catch (NullReferenceException) {}

      base.OnAuthentication(filterContext);
}