0

我正在尝试创建一个简单的用户身份验证功能,但我无法让它工作。这是我正在处理的代码:

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 ,但即使在这个非常简单的示例中,我也无法让它工作。

有人可以告诉我我错过了什么吗?

谢谢!

4

2 回答 2

0

我刚遇到同样的问题,是的,我同意我们需要将该主体保存到某个地方(cookie、会话)以供其他操作使用,因此,在 SetPrincipal 函数中我添加了

HttpContext.Current.Session["user"] = HttpContext.Current.User;

现在,问题是如何将其取回以进行其他操作,我脑海中的想法弹出窗口是扩展 AuthorizeAttribute 并覆盖 IsAuthrized 函数,它将首先读取会话,如果找到会话,它将返回 true,否则它将返回假。

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 控制器中的 [Authorize] 替换为 [MyAuthorizeAttribute]。

它非常适合我。

干杯

于 2015-02-28T22:02:20.520 回答
0

Login 方法仅为当前请求设置主体。请求完成后,主体上下文被清除,以便服务器可以处理其他用户的其他请求。当一个新请求到来时,从服务器的角度来看,主体上下文不再存在,如果没有恢复它,则该请求是未经身份验证的。

要解决此问题,您必须将登录方法中的某些内容返回给客户端。不仅是 bool ,而是 - 一个身份验证令牌。客户端可以用来验证进一步请求的东西。

它可以是任何东西。只要客户端记得将其附加到进一步的请求中,表单 cookie 就可以了。另一种常见的做法是将自定义身份验证令牌返回给客户端,然后由客户端附加到自定义身份验证标头中。由于表单 cookie 由表单身份验证模块处理,因此自定义标头将需要自定义 mvc 身份验证过滤器或自定义 asp.net 身份验证模块,以便在请求即将执行之前读取令牌、提取和恢复身份。

如果您不喜欢烘焙自己的令牌基础设施,我也推荐 OAuth2 令牌。有一本很棒的书,其中包含有关此方法和其他可能的身份验证方法的易于遵循的示例:

http://www.amazon.com/Pro-ASP-NET-Web-API-Security/dp/1430257822/ref=sr_1_1?ie=UTF8&sr=8-1&keywords=web+api+security

于 2013-11-03T21:44:07.683 回答