Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Asp.NETWebAPI中使类对象在请求的整个生命周期内可用?_C#_Asp.net Web Api2 - Fatal编程技术网

C# 如何在Asp.NETWebAPI中使类对象在请求的整个生命周期内可用?

C# 如何在Asp.NETWebAPI中使类对象在请求的整个生命周期内可用?,c#,asp.net-web-api2,C#,Asp.net Web Api2,这是我的密码。我已经为有效的令牌返回用户对象编写了验证令牌的登录名。但无法找到使其在控制器之间可用的方法 我不想使用身份 public class CustomAuthorize : AuthorizeAttribute { private const string AUTH_TOKEN = "AuthToken"; public override Task OnAuthorizationAsync(HttpActionContext actionContext, Cancel

这是我的密码。我已经为有效的令牌返回用户对象编写了验证令牌的登录名。但无法找到使其在控制器之间可用的方法

我不想使用身份

public class CustomAuthorize : AuthorizeAttribute
{
    private const string AUTH_TOKEN = "AuthToken";

    public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        AllowAnonymousAttribute allowAnonymousAttribute = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().FirstOrDefault();

        if (allowAnonymousAttribute != null)
        {
            return Task.FromResult<object>(null);
        }

        if (actionContext.Request.Headers.Contains(AUTH_TOKEN))
        {
            var authToken = actionContext.Request.Headers.GetValues(AUTH_TOKEN).First();
            var user = Utility.GetUserByToken(authToken);

            if (user != null)
            {
                //
                // how to make this `user` object available across the controllers
                //

                return Task.FromResult<object>(null);
            }
            else
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new CustomError() { Code = 100, Message = "Invalid Access Token" });
                return Task.FromResult<object>(null);
            }
        }
        else
        {
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, new CustomError() { Code = 100, Message = "Invalid Access Token" });
            return Task.FromResult<object>(null);
        }
    }
}
public类CustomAuthorize:authorized属性
{
私有常量字符串AUTH_TOKEN=“AuthToken”;
AuthorizationAsync上的公共重写任务(HttpActionContext actionContext,CancellationToken CancellationToken)
{
AllowAnyMousAttribute AllowAnyMousAttribute=actionContext.ActionDescriptor.GetCustomAttributes().FirstOrDefault();
if(allowAnonymousAttribute!=null)
{
返回Task.FromResult(空);
}
if(actionContext.Request.Headers.Contains(AUTH_令牌))
{
var authToken=actionContext.Request.Headers.GetValues(AUTH_TOKEN).First();
var user=Utility.GetUserByToken(authToken);
如果(用户!=null)
{
//
//如何使此“用户”对象在控制器中可用
//
返回Task.FromResult(空);
}
其他的
{
actionContext.Response=actionContext.Request.CreateSponse(HttpStatusCode.Unauthorized,new CustomError(){Code=100,Message=“无效访问令牌”});
返回Task.FromResult(空);
}
}
其他的
{
actionContext.Response=actionContext.Request.CreateSponse(HttpStatusCode.Unauthorized,new CustomError(){Code=100,Message=“无效访问令牌”});
返回Task.FromResult(空);
}
}
}

请帮助…

一种方法是扩展ApiController,它是控制器用作基类的部分

定义自定义控制器

public class CustomController : ApiController
{
    projected User _user;

}

对于所有其他控制器,请将其用作基类,并且_user对象应该可以从所有控制器访问。

您的问题有点不清楚-我假设您指的是这一行:

var user = Utility.GetUserByToken(authToken);
如果是这样,那么我可能会有一个解决办法。因此,基本问题是,您不能简单地将此变量保存在当前控制器中的位置,您需要了解您所处的环境-每次不同的用户发出请求时,都会在当前控制器中创建不同的用户模型。要在用户发出请求时访问我的应用程序中的用户模型,我执行以下操作:

首先,您需要连接到ASP.NET的请求接收过程。这可以在
Global.asax.cs
文件中完成,但我更喜欢保持它的整洁,创建一个
PartialGlobal
类,并将
Global.asax.cs
标记为partial

然后创建
PartialGlobal
类:

 public partial class MvcApplication
{
    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        var request = HttpContext.Current.Request;
        var authHeader = request.Headers["Authorization"];

        //For API users
        if (authHeader != null)
        {
            var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
            if (authHeaderVal.Scheme.Equals("Basic", StringComparison.OrdinalIgnoreCase))
            {
                if (!string.IsNullOrEmpty(authHeaderVal.Parameter))
                {
                    AuthenticateUser(authHeaderVal.Parameter);
                }
            }
        }
        //For Regular Website Users
        else
        {
            HttpCookie authCookie = request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                //Extract the forms authentication cookie
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                // If caching userData field then extract
                var userModel = UsersBLL.DeserializeObject(authTicket.UserData);
                var principal = new UserPrincipal(userModel);
                SetPrincipal(principal);
            }
        }
    }

    private static bool AuthenticateUser(string credentials)
    {
        var model = UsersBLL.DecryptToken(credentials);
        if (!model.RefUser.HasValue)
        {
            return false;
        }

        SetPrincipal(new UserPrincipal(model));

        return true;
    }

    private static void SetPrincipal(UserPrincipal principal)
    {
        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
        {
            HttpContext.Current.User = principal;
        }
    }
}    
public class UserPrincipal : IPrincipal
{
    public IIdentity Identity { get; private set; }
    //Just a class with details like name,age etc.
    public UserModel Model { get; set; }

    public UserPrincipal(UserModel model)
    {
        this.Model = model;
        this.Identity = new GenericIdentity(model.Email);
    }        
}
UserPrincipal
类:

 public partial class MvcApplication
{
    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        var request = HttpContext.Current.Request;
        var authHeader = request.Headers["Authorization"];

        //For API users
        if (authHeader != null)
        {
            var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
            if (authHeaderVal.Scheme.Equals("Basic", StringComparison.OrdinalIgnoreCase))
            {
                if (!string.IsNullOrEmpty(authHeaderVal.Parameter))
                {
                    AuthenticateUser(authHeaderVal.Parameter);
                }
            }
        }
        //For Regular Website Users
        else
        {
            HttpCookie authCookie = request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                //Extract the forms authentication cookie
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                // If caching userData field then extract
                var userModel = UsersBLL.DeserializeObject(authTicket.UserData);
                var principal = new UserPrincipal(userModel);
                SetPrincipal(principal);
            }
        }
    }

    private static bool AuthenticateUser(string credentials)
    {
        var model = UsersBLL.DecryptToken(credentials);
        if (!model.RefUser.HasValue)
        {
            return false;
        }

        SetPrincipal(new UserPrincipal(model));

        return true;
    }

    private static void SetPrincipal(UserPrincipal principal)
    {
        Thread.CurrentPrincipal = principal;
        if (HttpContext.Current != null)
        {
            HttpContext.Current.User = principal;
        }
    }
}    
public class UserPrincipal : IPrincipal
{
    public IIdentity Identity { get; private set; }
    //Just a class with details like name,age etc.
    public UserModel Model { get; set; }

    public UserPrincipal(UserModel model)
    {
        this.Model = model;
        this.Identity = new GenericIdentity(model.Email);
    }        
}
注意
PartialGLobal
类中的行:
var model=UsersBLL.decryptoken(凭证)。在这里,我只是使用我创建的一个方法对我的令牌字符串进行解密,这样它就可以被反序列化,您可能不需要这样做

基本部分是
PartialGlobal
类的最后一步:

private static void SetPrincipal(UserPrincipal principal)
{
     Thread.CurrentPrincipal = principal;
     if (HttpContext.Current != null)
     {
         HttpContext.Current.User = principal;
     }
}
如果您了解用户的上下文,只需调用以下命令,即可在任何位置访问该上下文:

var principal = (UserPrincipal)HttpContext.Current.User;

在WebAPI案例中,当更多的控制器参与处理单个请求时,这是非常罕见的(对于子操作,在ASP.NETMVC中更常见一些,但我从未看到WebAPI中需要它)。您确定要在单个HTTP请求期间共享信息而不是“浏览器会话”吗?实际上,我想从
user
对象中知道用户ID,以便我可以使用它进行进一步处理。感谢您的回复,但在这种情况下,需要为UserPrincipal实现IPrincipal。您可以分享UserPrincipal的代码吗?当然可以:)。更新了我的帖子。当然,没问题!如何初始化_user对象?