我正在尝试编写一个ASP.NET MVC应用程序,它是我们的CRM的前端,它具有SOAP Web服务。我希望用户使用他们的CRM用户名和密码登录我的Web应用程序,然后针对CRM进行身份验证,在页面上进行Web服务调用等。
我开始考虑使用表单身份验证和实现自定义成员资格提供程序 - 我可以实现我需要的所有方法ValidateUser()
,但我遇到的问题是登录到CRM Web服务后给出一个必须与每个后续Web服务调用一起传递的令牌,我不知道我可以在哪里存储它。
所以我的问题是:
任何建议都将不胜感激
答案 0 :(得分:36)
您可以将身份验证令牌存储在窗体身份验证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
}
然后您可以编写自定义授权属性,该属性将读取此信息并设置自定义通用标识:
[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
...
}