我有这样的登录方法:
// POST: /Account/LogOn
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl, string corpid)
{
var sb = new StringBuilder();
sb.AppendLine("Logon HttpPost start");
sb.AppendLine(string.Format("returnUrl: {0}", returnUrl));
sb.AppendLine(string.Format("corpid: {0}", corpid));
sb.AppendLine(string.Format("model.UserName: {0}", model.UserName));
sb.AppendLine(string.Format("model.Password: {0}", model.Password));
try
{
sb.AppendLine(string.Format("ModelState.IsValid: {0}", ModelState.IsValid));
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
sb.AppendLine("Validated User");
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1
&& returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//")
&& !returnUrl.StartsWith("/\"))
{
sb.AppendLine("Redirect(returnUrl)");
return Redirect(returnUrl);
}
// need to decide whether to display the CustomerSummary, AccountScreen, or AddCustomer view
// AccountScreen if they only have 1 account tied to this logon
// AddCustomer if they do not havfe any tied to this logon
// CustomerSummary if they have more than 1 tied to this logon
var customers = _client.RequestCustomersForAccount(model.UserName);
if (!customers.Any())
{
// no accounts tied to this logon
sb.AppendLine("No accounts found for this login.");
sb.AppendLine("RedirectToAction(AddCustomer, Customer)");
return RedirectToAction("AddCustomer", "Customer");
}
if (customers.Count() == 1)
{
sb.AppendLine("1 accounts found for this login.");
sb.AppendLine("RedirectToAction(AccountScreen, Customer)");
model.AccountId = customers[0].AccountId;
sb.AppendLine(string.Format("customers[0].AccountId: {0}", customers[0].AccountId));
// only 1 account tied to this logon
return RedirectToAction("AccountScreen", "Customer", model);
}
if (customers.Count() > 1)
{
sb.AppendLine(string.Format("{0} accounts found for this login.", customers.Count()));
sb.AppendLine("RedirectToAction(CustomerSummary, Customer)");
// no accounts tied to this logon
return RedirectToAction("CustomerSummary", "Customer");
}
}
else
{
var msg = "The user name or password provided is incorrect.";
sb.AppendLine(msg);
ModelState.AddModelError("", msg);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
catch (Exception ex)
{
sb.AppendLine(string.Format("An error occured: {0}", ex));
WebPortalLogging.Logging.LogException("The following error occured: ", ex, _asName);
return null;
}
finally
{
WebPortalLogging.Logging.LogInfo(sb.ToString(), _asName);
}
}
当我到达线路FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
时,我得到了这个错误:
System.InvalidOperationException:未提供用户名。在ClientCredentials中指定用户名。
服务器堆栈跟踪:位于System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirementtokenRequirement、布尔disableInfoCard)System.ServiceModel.Channels.HttpChannelFactory.CreateAndOpenTokenProvider(TimeSpantimeout,AuthenticationSchemes authenticationScheme,EndpointAddresstarget,Uri via,ChannelParameterCollection channelParameters)System.ServiceModel.Channels.HttpChannelFactory.CreateAndOpenTokenProvidersCore(EndpointAddressto,Uri via,ChannelParameterCollection channelParameters,TimeSpantimeout,SecurityTokenProviderContainer&tokenProvider,SecurityTokenProviderContainer&proxyTokenProvider)System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.CreateAndOpenTokenProviders(TimeSpan超时)System.ServiceModel.Channels.HttpsChannelFactory.HttpsRequestChannel.OnOpen(TimeSpan超时)System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan超时)System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan超时)
在System.ServiceModel/Channels.CommunicationObject.Open(TimeSpa超时)System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan超时,CallOnceManager级联)System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpantimeout)(字符串action,布尔单向,ProxyOperationRuntime操作,Object[]ins,Object[]out,TimeSpan超时)System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessagemethodCall,ProxyOperationRuntime操作)System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage消息)在[0]处重新引发异常:在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessagereqMsg、IMessage retMsg)System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&msgData,Int32类型)SuburbanCustPortal.SuburbanService.ISuburbanService.RequestCustomersForAccount(字符串客户登录名)SuburbanCustPortal.Controller.AccountController.LogOn(LogOnModelmodel,String returnUrl,String corpid)在C:\work2\Doozer中软件\郊区\郊区客户门户\控制器\账户控制器.cs:line112
这段代码曾经运行过,我回去将其与运行时的代码进行了比较,除了日志记录之外,我没有看到任何其他变化。
这是我添加的日志:
Logon HttpPost start
returnUrl:
corpid:
model.UserName: user
model.Password: password
ModelState.IsValid: True
Validated User
An error occured: System.InvalidOperationException: The username is not provided. Specify username in ClientCredentials.
Server stack trace:
at System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement, Boolean disableInfoCard)
at System.ServiceModel.Channels.HttpChannelFactory.CreateAndOpenTokenProvider(TimeSpan timeout, AuthenticationSchemes authenticationScheme, EndpointAddress target, Uri via, ChannelParameterCollection channelParameters)
at System.ServiceModel.Channels.HttpChannelFactory.CreateAndOpenTokenProvidersCore(EndpointAddress to, Uri via, ChannelParameterCollection channelParameters, TimeSpan timeout, SecurityTokenProviderContainer& tokenProvider, SecurityTokenProviderContainer& proxyTokenProvider)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.CreateAndOpenTokenProviders(TimeSpan timeout)
at System.ServiceModel.Channels.HttpsChannelFactory.HttpsRequestChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at SuburbanCustPortal.SuburbanService.ISuburbanService.RequestCustomersForAccount(String customerloginname)
at SuburbanCustPortal.Controllers.AccountController.LogOn(LogOnModel model, String returnUrl, String corpid) in C:work2Doozer SoftwareSuburbanSuburbanCustPortalControllersAccountController.cs:line 112
正如你从日志中看到的,自从我通过这个检查后,我就和一个用户一起登录了:
if (Membership.ValidateUser(model.UserName, model.Password))
此外,我可以在本地计算机上运行此代码,并且不会出现任何错误。这些都指向同一个数据库,在本地发布。
有人看到我的问题是什么吗?
当我到达行FormsAuthentication.SetAuthCookie(model.UserName,model.ErememberMe)时;我得到这个错误:
堆栈跟踪显示异常是由以下行引发的:
var customers = _client.RequestCustomersForAccount(model.UserName);
这个调用可能失败了,因为您的Thread.CurrentPrincipal
尚未设置为已验证的用户(您设置了FormsAuthentication cookie,但直到下一个请求才会处理它)。
我不确定你为什么要在验证用户后做额外的工作,我建议你立即重定向,例如:
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1
&& returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//")
&& !returnUrl.StartsWith("/\"))
{
sb.AppendLine("Redirect(returnUrl)");
return Redirect(returnUrl);
}
Redirect(Request.UrlReferrer.ToString()); // Or wherever you want to redirect to