2015-07-19 66 views
1

我有一个ASP.NET身份库的自定义实现,主要使用Dapper而不是实体框架,主要来自教程:http://blog.markjohnson.io/exorcising-entity-framework-from-asp-net-identity/身份基于角色的授权不起作用

一切都很好,用我的AuthenticationManager签入和签出用户。但是,只要在用户登录后重定向到任何地方,httpcontext基本上都是null,用户不再被认证。如果我也使用[Authorize]属性,那么用户会自动声明为Unauthorized,并抛出401错误。

这里是我的AccountController的部分:

[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public async Task<ActionResult> Login(Login login, string redundant) 
{ 
    var master = new MasterModel(); 
    if (ModelState.IsValid && (!string.IsNullOrEmpty(login.Email) && !string.IsNullOrEmpty(login.PasswordHash))) 
    { 
     var user = await Models.User.FetchUserByEmail(login.Email); 
     if (user != null) 
     { 
      await SignInAsync(user, true); 
      master.User = user; // User is now signed in - No problem 
      return RedirectToAction("Overview", "Account", master); 
     } 
    } 
    TempData["Message"] = "Your username or password was not recognised. Please try again."; 
    return View(master); 
} 

[HttpGet] 
//[Authorize(Roles = "admin,subscriber")] // 403 when uncommented 
public ActionResult Overview(MasterModel master = null) 
{ 
    // master is just a blank new MasterModel ?? 
    if (!HttpContext.User.Identity.IsAuthenticated) 
    { 
     // User is always null/blank identity 
     TempData["Message"] = "Please log in to view this content"; 
     return RedirectToAction("Login", "Account", master); 
    } 

    var userName = string.IsNullOrEmpty(HttpContext.User.Identity.Name) 
     ? TempData["UserName"].ToString() 
     : HttpContext.User.Identity.Name; 

    var user = Models.User.FetchUserByEmail(userName).Result; 

    if (master == null) master = new MasterModel(); 
    master.User = user; 

    return View(master); 
} 

我UserStore实现了以下接口:

public class UserStore : IUserStore<User>, IUserPasswordStore<User>, IUserSecurityStampStore<User>, IQueryableUserStore<User>, IUserRoleStore<User> 

我Rolestore的只是实现IQueryableRoleStore<Role>

用户和角色只是分别实现IUserIRole

我错过了什么?

UPDATE1: 这里的AuthenticatonManager的一部分:

public IAuthenticationManager AuthenticationManager 
{ 
    get 
    { 
     return HttpContext.GetOwinContext().Authentication; 
    } 
} 

private async Task SignInAsync(User user, bool isPersistent) 
{ 
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); 
    var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); 
    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity); 
} 
+0

您是否设置了应用程序以使用cookie身份验证? –

+0

@WiktorZychla是的。我已经用当前的AuthenticationManager和调用的SignInAsync()方法更新了问题。作为参考,据我所知,SignIn是成功的。 – Dezzamondo

+1

我的意思是在IAppBuilder上调用'UseCookieAuthentication'。 SignIn可能只是不创建cookie。您可以使用像Fiddler这样的http调试器轻松验证它。 –

回答

0

感谢@WiktorZychla您指出了答案。

原来我错过了将cookie认证添加到IAppBuilder的基本步骤。

这里的OwinStartup.cs现在的样子供参考:

using Microsoft.AspNet.Identity; 
using Microsoft.Owin; 
using Microsoft.Owin.Security.Cookies; 
using Owin; 

[assembly: OwinStartup(typeof(appNamespace.OwinStartup))] 

namespace appNamespace 
{ 
    public class OwinStartup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      app.UseCookieAuthentication(new CookieAuthenticationOptions 
      { 
       AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
       LoginPath = new PathString("/Account/Login") 
      }); 

     } 
    } 
} 

希望这将节省别人撕裂他们的头发都重要!