来自Windows窗体的MVC WebAPI认证

本文关键字:WebAPI 认证 MVC Windows 窗体 来自 | 更新日期: 2023-09-27 18:03:20

我正在尝试制作一个Windows窗体应用程序,该应用程序插入ASP暴露的一些服务。. NET MVC的WebAPI,但我有很大的麻烦与认证/登录部分。

我似乎找不到一个例子来演示如何从Windows窗体中做到这一点,我发现的一切似乎都非常复杂,包括很多非常深入的管道,或者似乎针对其他ASP。. NET网站,而不是windows窗体。

我错过了什么吗?这是不可能的吗?或者这只是无心之过?我看过一些类似于. net WebApi认证的东西,它们声称可以做到这一点,但我不知道如何从Windows窗体的角度来使用cookie。我也浏览了http://blogs.msdn.com/b/webdev/archive/2012/08/26/asp-net-web-api-and-httpclient-samples.aspx,但仍然没有什么运气。

来自Windows窗体的MVC WebAPI认证

只需在服务器端创建身份验证令牌并将其存储在数据库甚至缓存中。然后将此令牌与win forms应用程序的请求一起发送。WebApi应该一直检查这个令牌。这已经足够好了,你可以完全控制你的认证过程。

让我来分享一下,它是如何为我工作的:

Object with Auth details:

public class TokenIdentity
{
    public int UserID { get; set; }
    public string AuthToken { get; set; }
    public ISocialUser SocialUser { get; set; }
}

Web API Auth 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);
    }
}

全球。asax注册:

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

这个想法是AuthCacheManager扩展了AuthManager并装饰了它的方法和属性。

您可以使用基于令牌的身份验证。这里有一篇很棒的文章,说明了如何编写一个使用RSA公共/私有加密的自定义动作过滤器。