[英]MVC WebAPI authentication from Windows Forms
我试图制作一个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并且仍然运气不佳。
只需在服务器端创建身份验证令牌,并将其存储在数据库甚至缓存中。 然后使用来自win表单应用程序的请求发送此令牌。 WebApi应始终检查此令牌。 它足够好,您可以完全控制您的身份验证过程。
让我分享一下,它对我有用:
具有Auth详细信息的对象:
public class TokenIdentity
{
public int UserID { get; set; }
public string AuthToken { get; set; }
public ISocialUser SocialUser { get; set; }
}
Web API Auth控制器:
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;
}
}
Auth缓存管理器:
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并修饰它的方法和属性。 如果缓存中没有任何内容,那么去检查数据库。
您可以使用基于令牌的身份验证 这是一篇很棒的文章,说明如何编写使用RSA公共/私有加密的自定义操作过滤器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.