With Forms Authentication when the app needs to redirect to sign-in page is there an event or any extensibility point that will let me do additional work to the request before it redirects to the sign-in page?
I would like to send additional information in the query string that could vary such that it wouldn't work to just statically embed that in the link in the loginUrl node in the web.config.
Edit: For clarification, I want to intercept the request prior to being redirected TO the login page.
Example:
<authentication mode="Forms">
<forms loginUrl="http://the/interwebs/login.aspx" timeout="2880"
enableCrossAppRedirects="true" />
</authentication>
And prior the user being redirected to http://the/interwebs/login.aspx I would like to be able to pack in query values so the url could end up something like http://the/interwebs/login.aspx?Action=Refresh
I've done this before with an http module. My example (stripped down), in vb.net. I'm just checking for a 401 status code and doing my own redirect. The big trick here was that I had to remove and add back the web.config httpModules to make sure my httpmodule stepped in from of the url authorization module. In my case I had some url rewriting for localization, and I needed to send the locale ID to the login page as it was lost by the normal redirect in the url authorization module. I made heavy use of Reflector to build up the base path (not shown), as these are private methods.
Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
AddHandler context.EndRequest, AddressOf Context_EndRequest
End Sub
Private Sub Context_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
If TypeOf sender Is HttpApplication Then
Dim hApplication As HttpApplication = DirectCast(sender, HttpApplication)
Dim hContext As HttpContext = hApplication.Context
If (hContext.Response.StatusCode = &H191) Then
hContext.Response.Redirect(String.Format("{0}?ReturnUrl={1}&someparam2={2}", basepath, HttpUtility.UrlEncode(hContext.Request.RawUrl), someparam2))
End If
End If
End Sub
web.config changes
<httpModules>
<clear/>
<!-- custom -->
<add name="SomeHttpModule" type="SomeCompany.SomeProduct.SomeHttpModule"/>
<!-- add back defaults, exlude PassportAuthentication, AnonymousIdentification, Profile -->
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule"/>
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>
<add name="RoleManager" type="System.Web.Security.RoleManagerModule"/>
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule"/>
</httpModules>
You can do this via handling the event HttpApplication.AuthenticateRequest
private void Application_AuthenticateRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = context.Request.Cookies[cookieName];
if (authCookie == null || string.IsNullOrEmpty(authCookie.Value))
{
//... do something
}
FYI, We currently do this via an IHttpModule implementation.
You don't have to use the Forms authentication's mechanism to redirect people to a URL. You can do that in code. Just sign them in and Redirect them yourself using Response.Redirect
.