Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am working on a little project for SharePoint 2010 that will allow users to authenticate with their OpenID (and maybe more later on).

How it currently works is I have a membership and role provider based on SQL. My login page uses DotNetOpenAuth to send an authenticationrequest to the OpenID endpoint. If I get a positive response I read the e-mail address from the OpenID persona and create a session for the MembershipUser that has that e-mail address (if I know the endpoint he's from). If that user doesn't exist, I create a new MembershipUser and store the endpoint in the comment property (so that you can't simply edit your own persona to log in as another person's e-mail address).

This works, but the problem is in creating the session. I currently do this with the following bit of code:

//authenticate
SecurityToken token = SPSecurityContext.SecurityTokenForFormsAuthentication(new Uri(SPContext.Current.Web.Url),userProvider,roleProvider,username,user.GetPassword());         
SPFederationAuthenticationModule.Current.SetPrincipalAndWriteSessionToken(token);

But that bit only works if the membership provider doesn't encrypt passwords because, once encrypted, I can't just read the user's password and use it in that method.

I was hoping to find a way to just let a user log in but I can't seem to find a simple way of doing that.

Using

FormsAuthentication.SetAuthCookie(username, false);

Just creates an exception (I assume that's because that method is for standard FBA, and not claims-based FBA but I'm just guessing there. The built-in FBA login control with username and password does work, though.)

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)

Long story short, I would like a way to create tokens for my members without having to use their password.

Does anyone have some experience in this, or an idea of how I can get what I want?

Thanks in advance.

share|improve this question

1 Answer 1

In case someone else runs into the same situation, I'll say how I 'solved' the problem.

In a professional environment, you would most likely create your own membership provider / security token service so you can request tokens in your code without requiring the password of the user.

In my case (due to time constraints) I couldn't do that, so I took a simpler way out. Instead of using encrypted passwords (via IIS) I used hashed passwords (set that manually in the web.config). I also made sure to allow resetting of passwords for my membership provider. Then I used the following code to issue a token:

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);            

Practically, this means that the forms user has his password reset each time I log him in, but since he never actually uses his password it's not that big of an issue. It works well enough to quickly show OpenID support in SharePoint.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.