Redirect user after successful (fake) login in OpenID Offline Provider
Many days ago, I asked this question and I'm set with a working offline OpenID provider (I guess).
What I want is a simple login text box for OpenID identifier which will automatically accept the user and consider the user as logged in, then I want him to be redirected to the main products page (Products => Index).
But, what I didn't know (and didn't find on the internet) is how to go on after the fake authentication process.
I tried to do this:
[HttpPost]
public ActionResult Login(string openid)//openid is the identifier taken from the login 开发者_运维知识库textbox
{
var rely = new OpenIdRelyingParty();
var req = rely.CreateRequest(openid);
req.RedirectToProvider();
return RedirectToAction("Index", "Products");
}
First of all, it is not being redirected in the 4th line (instead the login page is refreshed) and second, no authenticated user is really there, I mean when I checked User
in Watch window, it is not null but Username is empty and there is no authenticated identity which, I guess, means that there is no cookies set.
P.S:
1. No exceptions are being thrown. But when I try to call FormsAuthentication.RedirectFromLogin() method I get an exception (Server cannot modify cookies after HTTP headers have been set).
2. Index action method is marked with [Authorize] attribute, and so when someone tries to browse Products
it is redirected to the login screen, but when he logs in (fake login), shouldn't he be redirected back to Products page?
I tried this also:
[HttpPost]
public ActionResult Login(string openid)
{
var rely = new OpenIdRelyingParty();
return rely.CreateRequest(openid).RedirectingResponse.AsActionResult();
}
But no luck.
What did I miss? and how to make it work as expected? I can depend on myself but I need a decent documentation for OpenID especially for the offline local provider.
Check this example: OpenID and OAuth using DotNetOpenAuth in ASP.NET MVC
public ActionResult OpenId(string openIdUrl)
{
var response = Openid.GetResponse();
if (response == null)
{
// User submitting Identifier
Identifier id;
if (Identifier.TryParse(openIdUrl, out id))
{
try
{
var request = Openid.CreateRequest(openIdUrl);
var fetch = new FetchRequest();
fetch.Attributes.AddRequired(WellKnownAttributes.Contact.Email);
fetch.Attributes.AddRequired(WellKnownAttributes.Name.First);
fetch.Attributes.AddRequired(WellKnownAttributes.Name.Last);
request.AddExtension(fetch);
return request.RedirectingResponse.AsActionResult();
}
catch (ProtocolException ex)
{
_logger.Error("OpenID Exception...", ex);
return RedirectToAction("LoginAction");
}
}
_logger.Info("OpenID Error...invalid url. url='" + openIdUrl + "'");
return RedirectToAction("Login");
}
// OpenID Provider sending assertion response
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
var fetch = response.GetExtension<FetchResponse>();
string firstName = "unknown";
string lastName = "unknown";
string email = "unknown";
if(fetch!=null)
{
firstName = fetch.GetAttributeValue(WellKnownAttributes.Name.First);
lastName = fetch.GetAttributeValue(WellKnownAttributes.Name.Last);
email = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);
}
// Authentication
FormsAuthentication.SetAuthCookie(userName: email, createPersistentCookie: false);
// Redirection
return RedirectToAction("Index", "Products");
case AuthenticationStatus.Canceled:
_logger.Info("OpenID: Cancelled at provider.");
return RedirectToAction("Login");
case AuthenticationStatus.Failed:
_logger.Error("OpenID Exception...", response.Exception);
return RedirectToAction("Login");
}
return RedirectToAction("Login");
}
Basically, your action method is called twice:
The first time by your form being submitted by the user.
The second time is a call back (redirect) from the OpenID provider.
This time, there will be a value for the response
. If response.Status
is valid, you can log your user in using the FormsAuthentication
class and finally you can redirect him to your main products page.
精彩评论