文章目錄
如何在 ASP.NET MVC 的 BaseController 或是 Controller 建構式中存取 ASP.NET Identity User 資料
從 ASP.NET MVC 5 開始預設使用 ASP.NET Identity ,全新的會員身份系統(membership system),雖然已經實際在幾個專案使用,但因為對 ASP.NET Identity 沒有很清楚的理解跟認識,每次使用時都會遇到類似,甚至相同的問題。 最近的專案又遇到了相同狀況(慚愧~~),趁著記憶猶新趕快紀錄一下,避免每次遇到都要查好久
文章大綱
- 錯誤訊息
- 新增 BaseController
- 建立 ASP.NET Identity 資料服務
- 其他 Controller 實際使用
- Web API 下的作法
1. 錯誤訊息
訊息內容
Object reference not set to an instance of an object.
錯誤截圖
2. 新增 BaseController
加上
[Authorize]
attibute[Authorize] public class BaseController : Controller
新增 User property
IUser _UserData; public IUser UserData { get { return _UserData; } set { _UserData = value; } }
建立 BaseController 建構式
- 取得執行緒目前原則
- 檢查目前原則是否有效登入
依執行原則中的名稱反查 User 資料
public BaseController() { var userFromAuthCookie = System.Threading.Thread.CurrentPrincipal; if (userFromAuthCookie != null && userFromAuthCookie.Identity.IsAuthenticated) // && !String.IsNullOrEmpty(userFromAuthCookie.Identity.Name)) { string userNameFromAuthCookie = userFromAuthCookie.Identity.Name; _UserData = UserRepository.GetUser(userNameFromAuthCookie); } }
完整程式碼
[Authorize] public class BaseController : Controller { IUser _UserData; public IUser UserData { get { return _UserData; } } public BaseController() { var userFromAuthCookie = System.Threading.Thread.CurrentPrincipal; if (userFromAuthCookie != null && userFromAuthCookie.Identity.IsAuthenticated) { string userNameFromAuthCookie = userFromAuthCookie.Identity.Name; _UserData = UserRepository.GetUser(userNameFromAuthCookie); } } }
3. 建立 ASP.NET Identity 資料服務
public static class UserRepository
{
public static IUser GetUser(string username)
{
var UserManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
return UserManager.FindByName(username);
}
}
4. 其他 Controller 實際使用
繼承 BaseController
public class HomeController : BaseController
自訂 property
private string userID;
建構式存取 BaseController property
public HomeController() { userID = UserData.Id; }
5. Web API 下的作法
相關做法請參考 Identity 2.0 User Identity is null in MVC 5 controller initializer
加入自訂 Authorize attibute
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()); } } }
將自訂的 Authorize attibute 加入 Startup.cs 中
public void Configuration(IAppBuilder app) { ConfigureOAuth(app); HttpConfiguration config = new HttpConfiguration(); WebApiConfig.Register(config); config.Filters.Add(new MyAuthorizeAttribute()); }
使用 ActionContext 取得 userId
Guid userId = (Guid) ActionContext.Request.Properties["userId"];
參考資料
文章作者 Yowko Tsai
上次更新 2021-11-03
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。