views:

494

answers:

2

When an user clicks a link in my site that requires authentication, the browser is redirected to the login page. The login page includes a returnUrl querystring parameter. The problem is that if the user authenticates using OpenID, the providers redirects the user back to the login page and doesn't include the returnUrl parameter, which is pretty boring because I redirect the user to the home page instead of the page that was tried.

I'm using DotNetOpenID, is there a way to fix this?

+1  A: 

If you want the OpenID provider to return to a different url, you need to use the OpenIdRelyingParty.CreateRequest(Identifier userSuppliedIdentifier, Realm realm, Uri returnToUrl) method when creating the authentication request.

However, usually you don't want the OpenID provider to redirect back to the url that initiated the login sequence within your app. You want to come back to the point where you initiated the OpenID auth to process properly the response. Helps with encapsulating the OpenID layer from the rest of the logic in your app.

Here's an example:

In my ASP.NET MVC app, I have a User controller with Authenticate action which handles login requests.

The Authenticate action checks OpenIdRelyingParty.Response. If it's null, the action calls RedirectToProvider. The provider returns back to the same action, where I check the Respons.Status. If it is AuthenticationStatus.Authenticated I use FormsAuthentication.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, true) to go back to the page the user initiated the login seqeuence from.

However, if the status is 'AuthenticationStatus.Failed or 'AuthenticationStatus.Canceled, I can offer the user steps to resolve this issues. I can offer them to correct their OpenID if mistyped or to login with username/password instead. (I support both OpenID and username/password authentication for the same identitites)

My login box is on every page. If the OpenID provider redirected me back to the page that initiated the login request, chances are that page won't be capable of processing the failure properly.

Franci Penov
I made it similar to yours, but the problem is that when the provider redirects the user back to my authenticate action, the returnUrl parameter is gone... so RedirectFromLoginPage doesn't work...
Bruno
Franci Penov
+2  A: 

It's really easy, Bruno. Just call

IAuthenticationRequest.AddCallbackArguments("returnUrl", Request.QueryString["returnUrl"]);

That will tell DotNetOpenId to preserve the returnUrl argument on the login page and get the behavior you want. I have to disagree with Franci regarding separating the URL that displays the login page from the one that processes the result. For ASP.NET MVC sites that may be appropriate, but for ASP.NET web forms that's really not the way to go, since in addition to displaying any error to the user you'll no doubt want to also display the login form again. Besides, as far as separation of logic, the DotNetOpenId library does all the heavy-lifting for you, so there's hardly any logic in your code-behind page anyway.

Andrew Arnott
Should that be AddCallbackArgument**s**
cantabilesoftware
Yes, thanks. I've corrected my answer.
Andrew Arnott