Hi all,
I'm trying to approximate Single Sign on. Currently, the most workable solution involves the user imputing details on my site before being sent off to goggle Apps to authenicate.
I'm using dotnetopenauth to send and recieve the requests
This means that it takes no account of google apps login cookies should they be present.
There are several questions covering this already. But none seem to have an answer to this.
This is the current code (note that I'm constraining the possible domains that can be used to just google apps for my domain):
public ActionResult Authenticate(string returnUrl)
{
string input=Request.Form["openid_identifier"]+"@example.com";
openid.DiscoveryServices.Clear();
openid.DiscoveryServices.Insert(0, GoogleAppsDiscovery); // it should be first if we don't clear the other discovery services
var response = openid.GetResponse();
if (response == null)
{
// Stage 2: user submitting Identifier
Identifier id;
if (Identifier.TryParse(input, out id))
{
try
{
return openid.CreateRequest(input).RedirectingResponse.AsActionResult();
}
catch (ProtocolException ex)
{
ViewData["Message"] = ex.Message;
return View("Login");
}
}
else
{
ViewData["Message"] = "Invalid identifier";
return View("Login");
}
}
else
{
// Stage 3: OpenID Provider sending assertion response
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false);
var results = userstable.Select(response.FriendlyIdentifierForDisplay);
if (results.Count() > 0)
{
Session["FriendlyIdentifier"] = results.ElementAt(0).UserFName;
return RedirectToAction("Index", "Home", results.ElementAt(0).UserID);
}
else
{
UsersDataModel user = new UsersDataModel();
user.OpenID = response.ClaimedIdentifier.ToString();
user.UserID = Utils.HashToBase64(response.FriendlyIdentifierForDisplay);
user.Type = "Empolyee";
userstable.Insert(user);
//return RedirectToAction("Register");
}
if (!string.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
case AuthenticationStatus.Canceled:
ViewData["Message"] = "Canceled at provider";
return View("Login");
case AuthenticationStatus.Failed:
ViewData["Message"] = response.Exception.Message;
return View("Login");
}
}
return new EmptyResult();
}
The only difference between this code and the normal pattern are the following lines:
openid.DiscoveryServices.Clear();
openid.DiscoveryServices.Insert(0, GoogleAppsDiscovery); // it should be first if we don't clear the other discovery services
These lines correctly setup OpenId to process the response from google apps.
As I said, this works only if the user inputs his/her email address first. i can't find a way of automatically redirecting to the Google Apps Login
In normal gmail, if I pass the user off to: https://www.google.com/accounts/o8/id instead of processing the input, google will have the user input login details on their site rather than on mine. It will skip that if there are cookies and just pass the user right back to my site with no fuss.
I would like to have the same behavior for my site for the google apps logins.
Additionally, it would be nice if I could constrain the logins to my google apps domain.
There are a couple of URLs floating around:
https://www.google.com/accounts/o8/site-xrds?hd=example.com or https://www.google.com/a/example.com/o8/id
But even with those lines of code I pointed out earlier, dontnetopenauth refuses to see an openid endpoint at either address.
Even the sample in dotnetaopenauth for webforms still requires user input.
Any help would be most appreciated.