我正在开发一个SharePoint 2010的小项目,该项目允许用户使用他们的OpenID进行身份验证(稍后可能会更新)。
它目前的工作原理是我有一个基于SQL的成员资格和角色提供程序。我的登录页面使用DotNetOpenAuth向OpenID端点发送身份验证请求。如果我得到肯定的回复,我会从OpenID角色中读取电子邮件地址,并为具有该电子邮件地址的MembershipUser创建会话(如果我知道他来自的端点)。如果该用户不存在,我创建一个新的MembershipUser并将该端点存储在comment属性中(这样您就不能简单地编辑自己的角色以作为另一个人的电子邮件地址登录)。
这有效,但问题在于创建会话。我目前使用以下代码执行此操作:
//authenticate
SecurityToken token = SPSecurityContext.SecurityTokenForFormsAuthentication(new Uri(SPContext.Current.Web.Url),userProvider,roleProvider,username,user.GetPassword());
SPFederationAuthenticationModule.Current.SetPrincipalAndWriteSessionToken(token);
但是,只有会员提供商不对密码进行加密时,该位才有效,因为一旦加密,我不能只读取用户的密码并在该方法中使用它。
我希望找到让用户登录的方法,但我似乎无法找到一种简单的方法。
使用
FormsAuthentication.SetAuthCookie(username, false);
只是创建一个异常(我假设这是因为该方法适用于标准FBA,而不是基于声明的FBA,但我只是在猜测。但是,使用用户名和密码的内置FBA登录控件确实有用。)
System.ArgumentException: Exception of type 'System.ArgumentException' was thrown. Parameter name: encodedValue
at Microsoft.SharePoint.Administration.Claims.SPClaimEncodingManager.DecodeClaimFromFormsSuffix(String encodedValue)
at Microsoft.SharePoint.Administration.Claims.SPClaimProviderManager.GetProviderUserKey(String encodedSuffix)
at Microsoft.SharePoint.SPGlobal.CreateSPRequestAndSetIdentity(SPSite site, String name, Boolean bNotGlobalAdminCode, String strUrl, Boolean bNotAddToContext, Byte[] UserToken, String userName, Boolean bIgnoreTokenTimeout, Boolean bAsAnonymous)
at Microsoft.SharePoint.SPWeb.InitializeSPRequest()
at Microsoft.SharePoint.WebControls.SPControl.EnsureSPWebRequest(SPWeb web)
at Microsoft.SharePoint.WebControls.SPControl.SPWebEnsureSPControl(HttpContext context)
at Microsoft.SharePoint.ApplicationRuntime.BaseApplication.Application_PreRequestHandlerExecute(Object sender, EventArgs e)
at Microsoft.SharePoint.ApplicationRuntime.SPRequestModule.PreRequestExecuteAppHandler(Object oSender, EventArgs ea)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
长话短说,我想要一种为我的会员创建令牌而无需使用密码的方法。
有没有人有这方面的经验,或者我如何得到我想要的东西?
提前致谢。
答案 0 :(得分:1)
如果其他人遇到同样的情况,我会说我是如何“解决”这个问题的。
在专业环境中,您很可能会创建自己的会员提供商/安全令牌服务,这样您就可以在代码中请求令牌而无需用户的密码。
在我的情况下(由于时间限制)我不能这样做,所以我采取了更简单的方法。我没有使用加密的密码(通过IIS),而是使用哈希密码(在web.config中手动设置)。我还确保允许我的会员提供商重置密码。然后我使用以下代码发出令牌:
MembershipUser user = membershipProvider.GetUser(username, true);
if(user == null)
{
//create new user here
}
string password = user.ResetPassword();
SecurityToken token = SPSecurityContext.SecurityTokenForFormsAuthentication(new Uri(SPContext.Current.Web.Url), membershipProviderName, roleProviderName, user.UserName, password, false);
SPFederationAuthenticationModule.Current.SetPrincipalAndWriteSessionToken(token);
实际上,这意味着表单用户每次登录时都会重置密码,但由于他从未真正使用他的密码,因此这并不是一个大问题。它足以在SharePoint中快速显示OpenID支持。