我正在尝试创建一个简单的用户身份验证功能,但我无法让它工作。 这是我正在处理的代码:
public class LoginController : ApiController
{
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
public bool Login(string token)
{
//Check token
if (.....)
{
//Authenticate user
var identity = new GenericIdentity("Test user");
SetPrincipal(new GenericPrincipal(identity, new string[]{"Test role"}));
}
}
[Authorize]
public string TestFun()
{
return "Hello " + User.Identity.Name;
}
}
因此,如果我首先尝试调用方法TestFun()
,它会返回错误代码401。
但是,当我调用方法Login()
时,它应该以某种方式保存用户凭据,但这是我迷路的地方,我无法让它工作。
TestFun()
, Login()
也会始终返回错误代码401。
如果我尝试将return "Hello " + User.Identity.Name;
放入Login()
函数中,则返回正确的用户名,但在TestFun()
中,用户不可用。
我甚至尝试过使用Sessions和FormsAuthentication,但即使是这个非常简单的例子,我也无法让它工作。
有人可以告诉我我错过了什么吗?
谢谢!
答案 0 :(得分:0)
Login方法仅设置当前请求的主体。请求完成后,主要上下文将被清除,以便服务器可以处理其他用户的其他请求。当一个新的请求出现时,从服务器的角度来看,主要的上下文不再存在,如果没有恢复,请求是未经身份验证的。
要解决此问题,您必须将登录方法中的内容返回给客户端。不仅是博尔而是 - 身份验证令牌。客户可以用来验证进一步请求的东西。
它可能是任何东西。只要客户记得将其附加到进一步的请求,表单cookie就可以了。另一种常见做法是将自定义身份验证令牌返回给客户端,然后由客户端在自定义身份验证标头中附加。由于表单Cookie由表单身份验证模块处理,因此自定义标头需要自定义mvc身份验证过滤器或自定义asp.net身份验证模块,以便令牌被加入,身份在之前提取和恢复 请求即将执行。
如果您不想烘焙自己的令牌基础架构,我还会推荐OAuth2令牌。有一本很棒的书包含了关于这个和其他可能的身份验证方法的简单例子:
答案 1 :(得分:0)
我刚刚遇到同样的问题,是的,我同意我们需要将该主体保存到某个地方(cookie,会话)以供其他操作使用,因此,在SetPrincipal函数中我添加了
HttpContext.Current.Session["user"] = HttpContext.Current.User;
现在,问题是如何将其恢复为其他操作,我脑海中的想法弹出是扩展AuthorizeAttribute并覆盖IsAuthrized函数,它将首先读取会话,如果找到会话,它将返回true,否则它将返回false。
namespace BinZ
{
public class MyAuthorizeAttribute:AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext actionContext) {
HttpContext.Current.User = HttpContext.Current.Session["user"] as IPrincipal;
return HttpContext.Current.User != null;
}
}
}
请记得在WebApi控制器中将[授权]替换为[MyAuthorizeAttribute]。
它非常适合我。
干杯