NoCache is not working as expected - asp.net-mvc-4

I used an Action Filter named [NoCache] to disable the access of login page after login by pressing the browser back button. The code is given below.
public class NoCacheAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuting(filterContext);
}
}
Then i referred it in login page as shown below.
[HttpPost]
[NoCache]
public ActionResult Index(Login objLogin)
{
return RedirectToAction("Index", "Blood");
}
But the result was unexpected. Instead of redirecting to Blood/Index action, the control transfered to the url : http://localhost:4506/Account/Login?ReturnUrl=%2fBlood
How can i correct this ?. Thanks.

This probably related with Form Authentication feature. Do you need it? If not, just don't use it.
For more details, please refer to:
How to remove returnurl from url?

Related

Blazor Wasm Identity Login/Logout event

In a .Net 5 Blazor WASM app using the standard identity from the Wasm template, I want to do something when a user logs in (or logs out). I've tried the RemoteAuthenticatorView in Authentication.razor:
#page "/authentication/{action}"
#using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="#Action"
OnLogInSucceeded="OnLoginSucceeded"
OnLogOutSucceeded="OnLogoutSucceeded1"
/>
#code{
[Parameter] public string Action { get; set; }
public async void OnLoginSucceeded()
{
// do something
}
public void OnLogoutSucceeded1()
{
// do something
}
}
and also, I tried in a component (where I really want to take the action to merge a shopping basket) :
AuthenticationStateProvider.AuthenticationStateChanged += OnAuthenticationStateChanged;
private async void OnAuthenticationStateChanged(Task<AuthenticationState> task)
{
var user = (await task).User;
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss:fff") + " InitialDataLoader -> OnAuthenticationStateChanged -> IsUserAuthenticated: " + user.Identity.IsAuthenticated);
}
I have breakpoints in each method and after I finally hit the Login breakpoint in both the RemoteAuthenticatorView and my component (it didn't break at all for a while), it now breaks but once only. If I logout - no logout event. If I login again, even as another user, I don't hit the breakpoints.
Is there a consistent method to generate or detect a login?
Turns out it was working ok, just the breakpoints were not working - no idea why not. I added Console.WriteLine messages to each & all events are hit correctly. So both techniques work as expected.

Log-in Portlet Hook

I hooked the login portlet to customize it's layout/design and it's working fine...
but when the user input is wrong/incorrect (authentication failed) the layout/design of my login hook is becomes like this...
I want to have SAME LAYOUT even if the authentication failed.
How will I achieve this?
Thank you in advance.
Here's my code in my hook of login struts action
public void processAction(
org.apache.struts.action.ActionMapping actionMapping,
org.apache.struts.action.ActionForm actionForm,
PortletConfig portletConfig, ActionRequest actionRequest,
ActionResponse actionResponse) throws Exception {
}
protected boolean isCheckMethodOnProcessAction() {
return _CHECK_METHOD_ON_PROCESS_ACTION;
}
protected void login(ThemeDisplay themeDisplay,
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
}
protected void postProcessAuthFailure(ActionRequest actionRequest,
ActionResponse actionResponse, StrutsPortletAction originalStrutsPortletAction, PortletConfig portletConfig) throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest
.getAttribute(WebKeys.THEME_DISPLAY);
PortletURL portleturl = PortletURLFactoryUtil.create(actionRequest,
"secondlogin_WAR_triumainportlet", themeDisplay.getPlid(),
PortletRequest.RENDER_PHASE);
portleturl.setParameter("saveLastPath", Boolean.FALSE.toString());
String redirect = ParamUtil.getString(actionRequest, "redirect");
if (Validator.isNotNull(redirect)) {
portleturl.setParameter("redirect", redirect);
}
else{
portleturl.setParameter("loginError", redirect);
}
portleturl.setWindowState(WindowState.MAXIMIZED);
actionResponse.sendRedirect(portleturl.toString());
originalStrutsPortletAction.processAction(originalStrutsPortletAction,
portletConfig, actionRequest, actionResponse);
}
private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
private static final Log _log = LogFactoryUtil.getLog(Sample.class);
You will need to adapt your styling of the error messages.
If an error occurs, this and another html fragment will get displayed on the response page. They both have the same markup.
<div class="alert alert-error"> Authentification failed. Please try again</div>
So you would need to style those, or even the surrounding wrapper div. As I am not informed about HOW you changed the css, I can not give you any further or more detailed advise.
[EDIT]
After rereading your question:
Maybe I did understand your question wrong. Is it possible, that you are referring to Layout of the Page itself? That would be related to the response rendering with maximized=true. I think you could modify this behaviour by overriding the StrutsAction.
[EDIT2]
According to your edit in the question ;)
Please try this:
portleturl.setWindowState(WindowState.NORMAL);

Overwrite the LoginWidget and Set DestinationPageUrl dynamically in Sitefinity

I want to add some custom code during the login function, in particular i want to redirect the user after login to the previous page.
For example: i'm on page A , i want to download something from this page, but i'm not authorized. Then pops a popup with link to the login page. After successful login i'm back on page A.
For this purpose i want to overwrite the LoginWidged and to set value to"this.DestinationPageUrl" dynamically.
I read about similar issues here and here, but there isn't an example how to overwrite this LoginWidget class.
I create CustomLoginControl.cs file in my project and register as a new custom control, but after rendering it on the page, it didn't work. Login button does not make nothing. I'm not sure what exactly have to do and which of methods have to overwrite.
namespace SitefinityWebApp.UserControls
{
public class CustomLoginControl : Telerik.Sitefinity.Web.UI.PublicControls.LoginWidget
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
this.DestinationPageUrl = "http://previousPage.com";
base.Render(writer);
}
}
}
Can you give me an example how to overwrite this class to work properly.
Version: Sitefinity 5.0, Claims-based authentication
I've done something similar but instead of overriding the login control you can subscribe and capture the UnauthorizedAccess event, send the user to your login page with your redirect page as a query string parameter. You'll need to add a Global.asax / Global.asax.cs file to your project, then add this to the Application_Start function:
protected void Application_Start(object sender, EventArgs e)
{
Bootstrapper.Initialized += BootstrapperInitialized;
}
Then add these two functions:
private void BootstrapperInitialized(object sender, ExecutedEventArgs e)
{
if (e.CommandName == "Bootstrapped")
{
EventHub.Subscribe<IUnauthorizedPageAccessEvent>(OnUnauthorizedAccess);
}
}
private void OnUnauthorizedAccess(IUnauthorizedPageAccessEvent unauthorizedEvent)
{
var manager = ConfigManager.GetManager();
string loginPage = manager.GetSection<ProjectConfig>().DefaultSite.FrontEndLoginPageUrl;
var redirectParam = unauthorizedEvent.RedirectUrl.Replace(string.Format("{0}?ReturnUrl=", loginPage), string.Empty);
var escaped = Uri.EscapeDataString(redirectParam);
unauthorizedEvent.HttpContext.Response.Redirect(string.Format("{0}?ReturnUrl={1}", loginPage, escaped));
}
You will also need to set your default front end login page in the settings under Administration -> Settings -> Advanced -> Project -> DefaultSite and the FrontEndLoginPageUrl setting.
This works for me on a 6.3 site, not sure if this is available in Sitefinity 5 or not.

ASP.Net MVC4 Mobile-Aware OutputCache

I'm working on upgrading an application from MVC3 to MVC4 and noticed something that I assumed (hoped?) would "just work".
CODE:
[OutputCache(Duration = 600, VaryByParam = "none")]
public ActionResult Index()
{
return View();
}
This is a textbook caching example for ASP.Net. Whenever a browser hits the page, it checks the cache to see if something exists, generates the view if not, and then sends the cached results.
This works great; however, playing around with the Mobile view functionality of MVC4, I noticed that the above code does not check to see if the Request is from a Mobile Device. So if I hit that route on a desktop, the desktop view will be displayed on my phone until cache is invalidated. The reverse is true as well (if I first hit the page with a phone, the desktop will then see the mobile view instead).
Is there a parameter that I could use to make this work like I hoped or am I looking at building a customer OutputCacheProvider?
After a bit more digging, I found a solution to the issue.
Updated Controller Action
[OutputCache(Duration = 600, VaryByCustom = "IsMobile")]
public ActionResult Index()
{
return View();
}
Override GetVaryByCustomString in Global.asax
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom.ToLowerInvariant() == "ismobile" && context.Request.Browser.IsMobileDevice)
{
return "mobile";
}
return base.GetVaryByCustomString(context, custom);
}
This is Correct GetVaryByCustomString method
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom.ToLowerInvariant() == "ismobile")
{
return context.GetVaryByCustomStringForOverriddenBrowser();
}
return base.GetVaryByCustomString(context, custom);
}

How do I navigate from one view to another in Caliburn.Micro?

So let me put it this way.
I have a LogInViewModel and a LogInView. There is a Login() method in the ViewModel that gets called if the user clicks on a button in the View. Now I want the dashboard to show if the login was successful. How do I do this? I can't find a clear answer to this in the documentation.
I assume that your dashboard is essentially your shell. In which case, you can bootstrap your LoginViewModel and in the Login method, after a successful login, you can show the DashboardViewModel and close the LoginViewModel using the Caliburn.Micro WindowManager.
Something like (using MEF):
Bootstrapper.cs
public class Bootstrapper : Caliburn.Micro.Bootstrapper<ILoginViewModel>
{
...
}
LoginViewModel.cs
public class LoginViewModel : Screen, ILoginViewModel
{
private readonly IWindowManager windowManager;
private readonly IDashboardViewModel dashboardViewModel;
[ImportingConstructor]
public LoginViewModel(IWindowManager windowManager, IDashboardViewModel dashboardViewModel)
{
this.windowManager = windowManager;
this.dashboardViewModel = dashboardViewModel;
}
public void Login()
{
// if login success...
this.windowManager.ShowDialog(this.dashboardViewModel);
this.TryClose();
}
}
I've just added a very simple login example SL4 project in my "lab repository" for Caliburn.Micro.
https://github.com/jenspettersson/Caliburn.Micro.Labs/tree/master/src/Login
It uses the Show class that Rob Eisenberg uses in his "Game Library" example to switch between views.
In the Login() method, it tells my Shell (your dashboard?) to show my LoginResultViewModel and sets the login result message.
yield return Show.Child<LoginResultViewModel>().In<IShell>().Configured(c => c.ResultMessage = "Successfully logged in!");
Check the code in my github repo.
I havent used Caliburn.Micro very much lately, so I am by no means an expert, but this way works for me.
//J
Edit: This answers how to navigate between views, if you want to show a "popup" to display if the login was successful, go with the other recomendations.