繁体   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