2015-07-19 118 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") 
      }); 

     } 
    } 
} 

希望這將節省別人撕裂他們的頭髮都重要!