c# - 来自 Windows 窗体的 MVC WebAPI 身份验证

标签 c# winforms asp.net-web-api

我正在尝试制作一个 Windows 窗体应用程序,该应用程序可插入 ASP.NET MVC WebAPI 公开的某些服务,但在身份验证/登录部分遇到了很多麻烦。

我似乎找不到一个示例来演示如何从 Windows 窗体执行此操作,我发现的所有内容似乎都非常复杂并且包含很多非常深入的管道,或者似乎针对其他 ASP.NET 网站,而不是窗体。

有什么我想念的吗?这是不可能的吗?或者它只是不是故意的?我看过这样的东西 .NET WebApi Authentication声称这样做,但我不知道如何从 Windows 窗体的角度使用 cookie。我也看过http://blogs.msdn.com/b/webdev/archive/2012/08/26/asp-net-web-api-and-httpclient-samples.aspx并且运气仍然很差。

最佳答案

只需在服务器端创建身份验证 token 并将其存储在您的数据库甚至缓存中。然后将此 token 与来自您的 win 表单应用程序的请求一起发送。 WebApi 应始终检查此 token 。这已经足够好了,您可以完全控制您的身份验证过程。

让我分享一下它对我的作用:

带有授权详细信息的对象:

public class TokenIdentity
{
    public int UserID { get; set; }

    public string AuthToken { get; set; }

    public ISocialUser SocialUser { get; set; }
}

Web API 授权 Controller :

  public class AuthController : ApiController
    {
        public TokenIdentity Post(
            SocialNetwork socialNetwork,
            string socialUserID,
            [FromUri]string socialAuthToken,
            [FromUri]string deviceRegistrationID = null,
            [FromUri]DeviceType? deviceType = null)
        {
            var socialManager = new SocialManager();

            var user = socialManager.GetSocialUser(socialNetwork, socialUserID, socialAuthToken);

            var tokenIdentity = new AuthCacheManager()
                .Authenticate(
                    user,
                    deviceType,
                    deviceRegistrationID);

            return tokenIdentity;
        }
    }

授权缓存管理器:

public class AuthCacheManager : AuthManager
    {
        public override TokenIdentity CurrentUser
        {
            get
            {
                var authToken = HttpContext.Current.Request.Headers["AuthToken"];
                if (authToken == null) return null;

                if (HttpRuntime.Cache[authToken] != null)
                {
                    return (TokenIdentity) HttpRuntime.Cache.Get(authToken);
                }

                return base.CurrentUser;
            }
        }

        public int? CurrentUserID
        {
            get
            {
                if (CurrentUser != null)
                {
                    return CurrentUser.UserID;
                }
                return null;
            }
        }

        public override TokenIdentity Authenticate(
            ISocialUser socialUser, 
            DeviceType? deviceType = null, 
            string deviceRegistrationID = null)
        {
            if (socialUser == null) throw new ArgumentNullException("socialUser");
            var identity = base.Authenticate(socialUser, deviceType, deviceRegistrationID);

            HttpRuntime.Cache.Add(
                identity.AuthToken,
                identity,
                null,
                DateTime.Now.AddDays(7),
                Cache.NoSlidingExpiration,
                CacheItemPriority.Default,
                null);

            return identity;
        }
    }

授权管理器:

 public abstract class AuthManager
    {
        public virtual TokenIdentity CurrentUser
        {
            get
            {
                var authToken = HttpContext.Current.Request.Headers["AuthToken"];
                if (authToken == null) return null;

                using (var usersRepo = new UsersRepository())
                {
                    var user = usersRepo.GetUserByToken(authToken);

                    if (user == null) return null;

                    return new TokenIdentity
                    {
                        AuthToken = user.AuthToken,
                        SocialUser = user,
                        UserID = user.ID
                    };
                }
            }
        }

        public virtual TokenIdentity Authenticate(
            ISocialUser socialUser, 
            DeviceType? deviceType = null, 
            string deviceRegistrationID = null)
        {
            using (var usersRepo = new UsersRepository())
            {
                var user = usersRepo.GetUserBySocialID(socialUser.SocialUserID, socialUser.SocialNetwork);

                user = (user ?? new User()).CopyFrom(socialUser);

                user.AuthToken = System.Guid.NewGuid().ToString();

                if (user.ID == default(int))
                {
                    usersRepo.Add(user);
                }

                usersRepo.SaveChanges();

                return new TokenIdentity
                {
                    AuthToken = user.AuthToken,
                    SocialUser = user,
                    UserID = user.ID
                };
            }
        }
    }

全局操作过滤器:

public class TokenAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (actionContext.Request.RequestUri.AbsolutePath.Contains("api/auth"))
        {
            return;
        }

        var authManager = new AuthCacheManager();

        var user = authManager.CurrentUser;

        if (user == null)
        {
            throw new HttpResponseException(HttpStatusCode.Unauthorized);
        }

        //Updates the authentication
        authManager.Authenticate(user.SocialUser);
    }
}

Global.asax 注册:

GlobalConfiguration.Configuration.Filters.Add(new AuthFilterAttribute());

想法是 AuthCacheManager 扩展 AuthManager 并装饰它的方法和属性。如果缓存中没有任何内容,则去检查数据库。

关于c# - 来自 Windows 窗体的 MVC WebAPI 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15349751/

相关文章:

javascript - 如何将 Angular 数组数据发送到 Controller ?

rest - 无法删除最后一个联系人 - 什么 Http 状态代码?

c# - 未处理的异常。 System.ArgumentNullException : Value cannot be null.(参数 'path1' )在 System.IO.Path.Combine(字符串路径1,字符串路径2)

c# - 用于在 UI 和 C 代码之间进行消息传递的套接字?

c# - ApiController 中的异步初始化

c# - 使用 C# 进行异地构建

c# - 在 WPF DataGrid 中手动添加行

c# - await Task 与 await Task.Run(voidMethod)

c# - ListView 中的自动宽度

c# - 如何使用winforms在多列模式下将项目添加到TreeViewAdv