问题
I am trying to find a way to prevent my aspnetcore application to add "?ReturnUrl=" to the URL. Does anyone know how to do it, using some kind of middleware.
I tried doing it like below but it did not have any effect:
public class RequestHandlerMiddleware
{
private readonly RequestDelegate _next;
public RequestHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if(context.Request.QueryString.HasValue && context.Request.QueryString.Value.Contains("?ReturnUrl="))
{
context.Request.QueryString = new QueryString(string.Empty);
}
await _next.Invoke(context);
}
}
public static class RequestHandlerMiddlewareExtension
{
public static IApplicationBuilder UseRequestHandlerMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestHandlerMiddleware>();
}
}
Registration in startup.cs
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/error");
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseAuthentication();
app.UseRequestHandlerMiddleware();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
}
Lastly, I have also tried some (tweaked) approaches from the older post regarding the same issue for .NET frameworks here (on stackoverflow) but also failed
Edit: I am not using any additional AuthorizationAttribute / Handler other then the 'standard' [Authorize] attribute. Only:
services.AddAuthorization();
Edit 2: I totally forgot that I also register a portion of the startup elsewhere in the application since it is shared:
public static IServiceCollection Load(IServiceCollection services, IConfiguration config)
{
services.AddDbContext<SqlContext>(options =>
{
options.UseSqlServer(config.GetConnectionString("DefaultConnection"));
});
services.AddIdentity<User, Role>(options =>
{
options.Lockout = new LockoutOptions
{
AllowedForNewUsers = true,
DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30),
MaxFailedAccessAttempts = 5
};
})
.AddEntityFrameworkStores<SqlContext>()
.AddDefaultTokenProviders()
.AddUserStore<UserStore<User, Role, SqlContext, Guid>>()
.AddRoleStore<RoleStore<Role, SqlContext, Guid>>()
.AddUserManager<ApplicationUserManager>();
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequiredLength = 5;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = true;
});
services.ConfigureApplicationCookie(options =>
options.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = ctx =>
{
if (ctx.Request.Path.StartsWithSegments("/api") &&
ctx.Response.StatusCode == (int)HttpStatusCode.OK)
{
ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
else if (ctx.Response.StatusCode == (int)HttpStatusCode.Forbidden)
{
ctx.Response.StatusCode = (int)HttpStatusCode.Forbidden;
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.FromResult(0);
}
});
return services;
}
回答1:
The first thing that comes to mind is :
[HttpGet]
public IActionResult LogIn()
{
if (!string.IsNullOrEmpty(Request.QueryString.Value))
return RedirectToAction("Login");
return View();
}
Which will remove QueryString part from the URL so that "ReturnUrl" will not stay on user address-bar for long and will reject any QueryString.
Better workaround would be creating your own version of AuthorizeAttribute which will not put a ReturnUrl in QueryString but it seems with new policy based authorization approach coming around, customizing AuthorizeAttribute is discouraged.
It might be also possible with policy based approach and creating a custom AuthorizationHandler
.
(I will post an update as soon as I try it out)
来源:https://stackoverflow.com/questions/49609240/disable-remove-returnurl-from-urls-in-netcore-2