簡體   English   中英

如何在ASP.NET MVC View中通過自定義Action Filter對用戶進行身份驗證?

[英]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,則非常簡單:

  1. 在web.config中設置auth mentod: <authentication mode="Forms" />

  2. 當登錄名和密碼有效時,使用FormsAuthentication.SetAuthCookie(userName, createPersistentCookie = true); 當用戶登錄應用程序時,此步驟僅執行一次。

  3. 然后你可以在視圖中使用屬性this.Request.IsAuthenticated或在控制器(或過濾器)中使用HttpContext.Current.Request.IsAuthenticated

  4. 它對conntrolers或actions(conntrollers中的公共方法)的屬性[Authorize]起作用。 當請求未經過身份驗證時,請求將重定向到默認(或在web.config中設置)登錄頁面。

如果要傳遞指示用戶是否經過身份驗證的布爾值,可能只需使用模型對象並將其傳遞給視圖即可。

或者您可以查看您的表單身份驗證以使Request.IsAuthenticated正常工作。 這個主題將有助於開始挖掘。

另一種選擇是考慮使用IAuthorizationFilter而不是自定義動作過濾器。 這個帖子將是一個起點。

希望有所幫助!

為了滿足您的目的,您需要將HttpContext.User設置為一些有效的IPrincipal。 因此,如果根據您的標准,用戶有效,您只需創建一個GenericPrinicpal並使用剛創建的實例設置HttpContext.User

像這樣的東西:

var genericIdentity=new GenericIdentity(user.Name,  "CustomAuthType");
var genericPrincipal=new GenericPrincipal(genericIdentity, null);

HttpContext.User = genericPrincipal;

對於GenericIdentityIsAuthenticated的值取決於Name屬性,因此只要GenericIdentity具有Name,就會認為它是經過身份驗證的。

在這個例子中,我設置了HttpContext.User而不是Thread.CurrentPrincipal這樣你就可以從Request.IsAuthenticated屬性中獲取IsAuthenticated

一些額外的相關信息:

GenericIdentity類

主體和身份對象

創建GenericPrincipal和GenericIdentity對象

替換主體對象

在您的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM