Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using OpenID in ASP.Net MVC3, where do I get the user data?

I realize OpenID is somewhat of a behemoth, or more complex than a typical registration form, but I feel I'm missing something here.

According to this question, I'm supposed to save the unique identifier key I'm given by my provider.

The provider will give you a unique ID for each user - this you need to save. It's how you will match up the user that just logged in with a record in your database.

In my code (taken from the MVC portion), this unique ID is given inside the switch in the LogOn() action method:

public ActionResult LogOn()
{
    var openid = new OpenIdRelyingParty();
    IAuthenticationResponse response = openid.GetResponse();

    if (response != null)
    {
        switch (response.Status)
        {
            case AuthenticationStatus.Authenticated:
                FormsAuthentication.RedirectFromLoginPage(
                    response.ClaimedIdentifier, false);  // <-------- ID HERE! "response.ClaimedIdentifier"
                break;
            case AuthenticationStatus.Canceled:
                ModelState.AddModelError("loginIdentifier",
                    "Login was cancelled at the provider");
                break;
            case AuthenticationStatus.Failed:
                ModelState.AddModelError("loginIdentifier",
                    "Login failed using the provided OpenID identifier");
                break;
        }
    }

    return View();
}

[HttpPost]
public ActionResult LogOn(string loginIdentifier)
{
    if (!Identifier.IsValid(loginIdentifier))
    {
        ModelState.AddModelError("loginIdentifier",
                    "The specified login identifier is invalid");
        return View();
    }
    else
    {
        var openid = new OpenIdRelyingParty();
        IAuthenticationRequest request = openid.CreateRequest(Identifier.Parse(loginIdentifier));

        // Require some additional data
        request.AddExtension(new ClaimsRequest
        {
            BirthDate = DemandLevel.NoRequest,
            Email = DemandLevel.Require,
            FullName = DemandLevel.Require
        });

        return request.RedirectingResponse.AsActionResult();
    }
}

Do I use this identifier for the FormsAuthentication.SetAuthCookie(IDHERE, true);?

What if I want to also save the users information, such as email, name, nickname or whatever. How do I get this collection of data from the relying party? In case this process depends on the provider I'm using, I am using Steam OpenID provider:

http://steamcommunity.com/openid http://steamcommunity.com/dev

like image 835
Only Bolivian Here Avatar asked Jul 17 '12 21:07

Only Bolivian Here


1 Answers

When You are successfully logged On, you can then do whatever you like with the received data: the Unique identifier alons with the claims you requested.

  1. Store the collected data in a database record.
  2. Save it in a cookie (either to send it as a token to your services if any or use it in your RP(Reliant party)).
  3. Use it along with a universal membership provider or a simple Sql provider.

Here is how you should have the second action in your controller:

    [AcceptVerbs(HttpVerbs.Post), ValidateInput(false)]
    public ActionResult LogOnPostAssertion(string openid_openidAuthData)
    {
        IAuthenticationResponse response;
        if (!string.IsNullOrEmpty(openid_openidAuthData))
        {
            var auth = new Uri(openid_openidAuthData);
            var headers = new WebHeaderCollection();
            foreach (string header in Request.Headers)
            {
                headers[header] = Request.Headers[header];
            }

            // Always say it's a GET since the payload is all in the URL, even the large ones.
            HttpRequestInfo clientResponseInfo = new HttpRequestInfo("GET", auth, auth.PathAndQuery, headers, null);
            response = this.RelyingParty.GetResponse(clientResponseInfo);
        }
        else
        {
            response = this.RelyingParty.GetResponse();
        }
        if (response != null)
        {
            switch (response.Status)
            {
                case AuthenticationStatus.Authenticated:
                    var token = RelyingPartyLogic.User.ProcessUserLogin(response);
                    this.FormsAuth.SignIn(token.ClaimedIdentifier, false);
                    string returnUrl = Request.Form["returnUrl"];
                    if (!String.IsNullOrEmpty(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                case AuthenticationStatus.Canceled:
                    ModelState.AddModelError("OpenID", "It looks like you canceled login at your OpenID Provider.");
                    break;
                case AuthenticationStatus.Failed:
                    ModelState.AddModelError("OpenID", response.Exception.Message);
                    break;
            }
        }

Other hints about what you can do with the received data: By creating a user login record in a UserLogin table in you reliant party database (your app). You will be able to validate the authentication and the status of your user the next time he will visit your app. You can also redirect him, the first time, to a specific page to collect more specific data that the OPenID provider did not provide (eg: age or gender). You can keep track of all user logins (OpenID (steam),google,liveID) and link them to the user. This will allow your unique user to login with whatever authentication provider he would like too.

For a full example using the Open ID authenticator you can look at the OpenId for MVC2 project1 from wich I extracted the previous example.

like image 134
Oualid KTATA Avatar answered Nov 15 '22 00:11

Oualid KTATA