MVC 5 How to define Owin LoginPath with localized routes
To enhance @martinoss answer, you may reach the same result without implementing a wrapper. Just copy the original handler, assign a new one that implements your redirection logic to modify context.RedirectionUri
, and at the end call the original handler.
CookieAuthenticationProvider provider = new CookieAuthenticationProvider();
var originalHandler = provider.OnApplyRedirect;
provider.OnApplyRedirect = context =>
{
//insert your logic here to generate the redirection URI
string NewURI = "....";
//Overwrite the redirection uri
context.RedirectUri = NewURI;
originalHandler.Invoke(context);
};
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString(url.Action("Login", "Account")),
Provider = provider
});
Without taking too much of responsibility on the url format etc, you can do something like the following
public static void Configuration(IAppBuilder app)
{
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString(url.Action("LogOn", "Account", new { area = "Account" })),
Provider = new CookieAuthenticationProvider
{
OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri.Replace(CultureHelper.GetDefaultCulture(), Thread.CurrentUiCulture.Name))
}
});
}
I exactly had the same problem and figured out a way to overcome this limitation.
In the CookieAuthenticationOptions
options, there is a "Provider" property which is initialized with the CookieAuthenticationProvider. This implements a method called ApplyRedirect
and a delegate OnApplyRedirect
.
My first idea was to overwrite this ApplyRedirect
and implement the required logic to handle localized routes. But unfortunately it can't be overriden. Passing my logic to OnApplyRedirect
causes to overwrite the default behavior. You theoretically can grab the source of this behavior, copy it into your project and modify it to your needs, but this is obviously not a good practice.
First, I decided to make a wrapper around the CookieAuthenticationProvider
with two extension points using delegates and preserving the default behavior except of the url that is used - or easier, work around the wrapper (thx to lafi).
Then in the auth configuration I added my custom logic to the provider:
public void ConfigureAuth(IAppBuilder app)
{
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
CookieAuthenticationProvider provider = new CookieAuthenticationProvider();
var originalHandler = provider.OnApplyRedirect;
//Our logic to dynamically modify the path (maybe needs some fine tuning)
provider.OnApplyRedirect = context =>
{
var mvcContext = new HttpContextWrapper(HttpContext.Current);
var routeData = RouteTable.Routes.GetRouteData(mvcContext);
//Get the current language
RouteValueDictionary routeValues = new RouteValueDictionary();
routeValues.Add("lang", routeData.Values["lang"]);
//Reuse the RetrunUrl
Uri uri = new Uri(context.RedirectUri);
string returnUrl = HttpUtility.ParseQueryString(uri.Query)[context.Options.ReturnUrlParameter];
routeValues.Add(context.Options.ReturnUrlParameter, returnUrl);
//Overwrite the redirection uri
context.RedirectUri = url.Action("login", "account", routeValues);
originalHandler.Invoke(context);
};
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString(url.Action("login", "account")),
//Set the Provider
Provider = provider
});
}
See also this code:
- CookieAuthenticationHandler
- CookieAuthenticationProvider
Hope it fits your needs.
UPDATE: For less confusion, I updated my answer to use @Lafis enhancement, not using a wrapper class to apply the extended behavior. Please also give credit to @Lafis when upvoting.
How about this:
var cao = new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider { OnApplyRedirect = ApplyRedirect }
};
app.UseCookieAuthentication(cao);
and
private static void ApplyRedirect(CookieApplyRedirectContext context)
{
UrlHelper _url = new UrlHelper(HttpContext.Current.Request.RequestContext);
String actionUri = _url.Action("Login", "Account", new { });
context.Response.Redirect(actionUri);
}