针对外部Web服务的ASP.NET MVC Forms身份validation

我正在尝试编写一个ASP.NET MVC应用程序,它是我们的CRM的前端,它具有SOAP Web服务。 我希望用户使用他们的CRM用户名和密码登录我的Web应用程序,然后针对CRM进行身份validation,在页面上进行Web服务调用等。

我开始考虑使用Forms身份validation和实现自定义成员资格提供程序 – 我可以实现我需要的所有方法来ValidateUser() ,但我遇到的问题是,在登录到CRM Web服务后,您将获得一个令牌,必须通过每个后续的Web服务调用传递,我不知道我可以在哪里存储它。

所以我的问题是:

  • 表单身份validation是这里的方式,还是自己处理所有身份validation并将令牌存储在Session中更直接。
  • 如果要进行表单身份validation,我应该在何处以及如何存储此类附加信息。 似乎喜欢使用表单身份validation,但随后将一大堆额外信息(与身份validation相关)撞到一个cookie或会话之外会有点混乱?

任何意见,将不胜感激

您可以将身份validation令牌存储在窗体身份validationcookie的userData部分中。 这样,每次请求都可以使用它。

因此,例如,一旦validation了用户的凭据,您就可以查询Web服务以获取令牌并手动创建并发出表单身份validationcookie:

 [HttpPost] public ActionResult LogOn(string username, string password) { // TODO: verify username/password, obtain token, ... // and if everything is OK generate the authentication cookie like this: var authTicket = new FormsAuthenticationTicket( 2, username, DateTime.Now, DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes), false, "some token that will be used to access the web service and that you have fetched" ); var authCookie = new HttpCookie( FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authTicket) ) { HttpOnly = true }; Response.AppendCookie(authCookie); // ... redirect } 

然后,您可以编写自定义authorize属性,该属性将读取此信息并设置自定义通用标识:

 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class MyAuthorizeAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { var isAuthenticated = base.AuthorizeCore(httpContext); if (isAuthenticated) { string cookieName = FormsAuthentication.FormsCookieName; if (!httpContext.User.Identity.IsAuthenticated || httpContext.Request.Cookies == null || httpContext.Request.Cookies[cookieName] == null) { return false; } var authCookie = httpContext.Request.Cookies[cookieName]; var authTicket = FormsAuthentication.Decrypt(authCookie.Value); // This is where you can read the userData part of the authentication // cookie and fetch the token string webServiceToken = authTicket.UserData; IPrincipal userPrincipal = ... create some custom implementation and store the web service token as property // Inject the custom principal in the HttpContext httpContext.User = userPrincipal; } return isAuthenticated; } } 

最后装饰需要使用此属性进行身份validation的控制器/操作:

 [MyAuthorize] public ActionResult Foo() { // HttpContext.User will represent the custom principal you created // and it will contain the web service token that you could use to // query the remote service ... }