ASP.. NET MVC表单对外部web服务的身份验证

本文关键字:服务 身份验证 web 对外部 NET MVC 表单 ASP | 更新日期: 2023-09-27 17:49:41

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

我开始考虑使用表单身份验证并实现自定义会员资格提供程序-我可以实现我需要喜欢ValidateUser()的所有方法,但我遇到的问题是,在登录到CRM web服务后,您将获得一个令牌,该令牌必须与每个后续web服务调用一起传递,我不确定我可以在哪里存储它。

我的问题是:

  • 是Forms Authentication的方法,还是自己处理所有的身份验证并将令牌存储在Session中更直接?
  • 如果表单身份验证是要走的路,我应该在哪里以及如何存储这样的附加信息。它似乎像使用表单身份验证,但然后将负载额外的信息(这是与身份验证相关的)撞击到cookie或会话之外,这将是有点混乱?

请指教

ASP.. NET MVC表单对外部web服务的身份验证

可以将身份验证令牌存储在表单身份验证cookie的userData部分中。这样每个请求都可用。

例如,一旦你验证了用户的凭据你可以查询web服务获取令牌并手动创建并发出表单认证cookie:

[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;
    }
}

最后用这个属性装饰需要身份验证的控制器/操作:

[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
    ...
}