![](/img/trans.png)
[英]Using ASP.NET MVC OutputCache while varying View content based on whether user is authenticated
[英]How to get whether user is authenticated by custom Action Filter in ASP.NET MVC View?
我有一個使用我的身份驗證過濾器的操作方法:
public class TutorAuthenticationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var req = filterContext.HttpContext.Request;
var auth = req.Headers["Authorization"];
if (!string.IsNullOrEmpty(auth))
{
var cred = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');
var user = new { Name = cred[0], Password = cred[1] };
if (userService.AuthorizeTutor(user.Name, user.Password))
{
return;
}
}
filterContext.HttpContext.Response.AddHeader("WWW-Authenticate", $"Basic realm= {BasicRealm}");
filterContext.Result = new HttpUnauthorizedResult();
}
}
我想在主頁上顯示一些用戶已經通過這種方式進行身份驗證,但這在我的視圖中不起作用:(
@if (Request.IsAuthenticated)
{
<h1>Hello</h1>
}
我知道它不起作用,因為我不使用Identity,但有什么方法可以做到這一點?
謝謝你的答案:)
為請求對象創建一個新的擴展方法說(IsUserAuthenticated())&在該方法中檢查用戶是否有效。 完成此操作后,您可以像使用Request.IsAuthenticated屬性一樣使用此新擴展方法。
以下是示例代碼,您需要根據需要進行調整。 (專門用於
userservice
初始化)
public class RequestValidator
{
public bool IsValid(HttpRequest request)
{
bool isValid = false;
//TODO: Intitialize your userService here, may be using DI or a concrete object creation depending on your implementation
var auth = request.Headers["Authorization"];
if (!string.IsNullOrEmpty(auth))
{
var cred = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');
var user = new { Name = cred[0], Password = cred[1] };
isValid = userService.AuthorizeTutor(user.Name, user.Password))
}
return isValid;
}
}
你的屬性會像這樣改變
public class TutorAuthenticationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var req = filterContext.HttpContext.Request;
RequestValidator validator = new RequestValidator();
if(validator.IsValid(request))
{
return;
}
filterContext.HttpContext.Response.AddHeader("WWW-Authenticate", $"Basic realm= {BasicRealm}");
filterContext.Result = new HttpUnauthorizedResult();
}
}
並且將在視圖上使用的擴展方法
public static class Extensions
{
public static bool IsUserAuthenticated(this HttpRequest request)
{
RequestValidator validator = new RequestValidator();
return validator.IsValid(request);
}
}
像這樣使用它
@if(Request.IsUserAuthenticated())
{
<p>Hello</p>
}
我想,在標頭中發送登錄名和密碼並不安全。 更好的解決方案是用戶驗證的一次。 檢查后,您可以檢查所有請求。
例如,如果您使用FormsAuthentication
和authCookie,則非常簡單:
在web.config中設置auth mentod: <authentication mode="Forms" />
當登錄名和密碼有效時,使用FormsAuthentication.SetAuthCookie(userName, createPersistentCookie = true);
當用戶登錄應用程序時,此步驟僅執行一次。
然后你可以在視圖中使用屬性this.Request.IsAuthenticated
或在控制器(或過濾器)中使用HttpContext.Current.Request.IsAuthenticated
。
它對conntrolers或actions(conntrollers中的公共方法)的屬性[Authorize]
起作用。 當請求未經過身份驗證時,請求將重定向到默認(或在web.config中設置)登錄頁面。
為了滿足您的目的,您需要將HttpContext.User
設置為一些有效的IPrincipal。 因此,如果根據您的標准,用戶有效,您只需創建一個GenericPrinicpal
並使用剛創建的實例設置HttpContext.User
。
像這樣的東西:
var genericIdentity=new GenericIdentity(user.Name, "CustomAuthType");
var genericPrincipal=new GenericPrincipal(genericIdentity, null);
HttpContext.User = genericPrincipal;
對於GenericIdentity
, IsAuthenticated
的值取決於Name屬性,因此只要GenericIdentity
具有Name,就會認為它是經過身份驗證的。
在這個例子中,我設置了HttpContext.User
而不是Thread.CurrentPrincipal
這樣你就可以從Request.IsAuthenticated
屬性中獲取IsAuthenticated
。
一些額外的相關信息:
在您的startup.cs文件中添加此項
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login"),
SlidingExpiration = true,
ExpireTimeSpan = TimeSpan.FromMinutes(40)
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.