我有一个使用我的身份验证过滤器的操作方法:
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,但有什么方法可以做到这一点吗?
感谢您的回答:)
答案 0 :(得分:3)
为请求对象创建一个新的扩展方法说(IsUserAuthenticated())&amp;在该方法中检查用户是否有效。 完成此操作后,您可以像使用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>
}
答案 1 :(得分:3)
我想,在标头中发送登录名和密码并不安全。更好的解决方案是用户验证的一次。检查后,您可以检查所有请求。
例如,如果您使用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中设置)登录页面。
答案 2 :(得分:1)
如果要传递指示用户是否经过身份验证的布尔值,可能只需使用模型对象并将其传递给视图即可。
或许您应该检查一下您的表单身份验证,以使Request.IsAuthenticated
正常工作。 This thread将有助于开始挖掘。
另一种选择是考虑使用IAuthorizationFilter而不是自定义操作过滤器。 This thread将是一个起点。
希望有所帮助!
答案 3 :(得分:1)
为了达到您的目的,您需要将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
具有名称,就会认为它已经过身份验证。
在此示例中,我设置了HttpContext.User
而不是Thread.CurrentPrincipal
,以便您可以从IsAuthenticated
属性中获取Request.IsAuthenticated
。
一些额外的相关信息:
Principal and Identity Objects
答案 4 :(得分:0)
添加此
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login"),
SlidingExpiration = true,
ExpireTimeSpan = TimeSpan.FromMinutes(40)
});