Spring MVC AngularJS Page Refresh/Redirect - angularjs

I am using angularjs with spring mvc in my application. It is a single page application where there is a login button and multiple tabs. Tabs are not visible unless the user logs in. After user logs in, the tabs will be visible (login button will not be visible) and user can navigate and use features under any tab. The URL of all these actions will be same (Ex: www.xyz.com/context/).
I have problem with session management here. If the session expires when the user is in any of these tabs, say tab no. 3, the page should be reset to initial state where login button is visible and tabs are not.
I have configured spring session management like below
<security:session-management invalid-session-url="/invalidSession">
<security:concurrency-control expired-url="/" />
</security:session-management>
On session expiry, I have spring mvc controller configured to handle it. Like the one below.
#RequestMapping(value="/invalidSession", method = RequestMethod.GET)
public ModelAndView invalidSession () {
ModelAndView model = new ModelAndView("redirect:/");
model.setStatus(HttpStatus.);
return model;
}
Though this method is called on session expiry, the redirect doesn't reset my page to its initial state where only login button is visible. Rather, it stays in the same state in tab no. 3 and all other tabs still visible. If I hit the browser refresh button, it works fine.
I have also tried using model.setStatus(HttpStatus.RESET_CONTENT); in the above controller method, it still doesn't work.
I went through the question in Spring security and angular javascript redirect to login page, but it is bit complicated for my requirement and my requirement is quite simple. I guess we should be able to handle it through session management of spring with appropriate redirect where it resets my page.
How can I achieve this?

Ok. I have taken an angular approach. I have used component ng-idle as outlined in Angular session timeout and management.
Also, I have removed spring session-management tag as ng-idle solves my requirement.

Related

How can I redirect unauthenticated Blazor Azure AD users to a different page than authenticated users?

I'm using the Blazor Server templates included with Visual Studio 2019.
In the template application that uses local authentication, When I view the page without being authenticated, the AuthorizeView tags work as expected, and the log in/out buttons on the navbar are displayed dynamically based on these tags. I am able to view the counter and weather forecast pages as a guest.
In the template application that uses Azure AD authentication, whenever I try and view a page without being authenticated, I'm redirected to the Microsoft login prompt. I'm still able to use the AuthorizeView tags to dynamically display components in the navbar, but what I want to be able to do is view the counter and weather forecast pages as a guest without getting redirected.
Is there any way to achieve this? Am I maybe missing something in App.razor?
Edit:
If I log out using the navbar link, and then navigate back with my browser, I can view the pages without authorization. But then when I refresh the page, I get sent back to https://login.microsoftonline.com/. What could be causing this? I want to view an unauthorized home page without getting redirected.
The behaviour you see is by design.
To change it you can make this change inside Startup.Configure :
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
//options.Filters.Add(new AuthorizeFilter(policy));
});
(and of course reduce this code to just services.AddControllersWithViews(); when you want to keep it this way.)
With this change you will have to block private pages with #attribute [Authorize] or with <AuthorizeView> and there is no automatic redirect to the login page.

Best options to display a popup for angularjs app based on conditions

I have an angularjs app with ASP.NET WebAPI2 REST APIs. There is a scenario where I have a display a popup for initiating a survey for end users (both authenticated and anonymous types). On clicking the popup options, the user will be redirected to another applicaiton which captures all the responses provided by the user.
There is no relation between the angularjs app and the survey application.
Now next time if the user revisits the application then in that case based on the previous action taken to fill the survey , I have to take a decision to display or hide the popup for the user.
I thought of cookies and localStorage as the options but I think are not ideal choices for this scenario.
Can anyone help me to know are there any other possible options to handle this scenario?
You can solve this using the redirection link.
For example if he finished correctly the Survey you will redirect him to:
www.myapp.com/survey/success
Than in the App you can do something like: get the URL parameters, if the parameters is success store it on localStorage so next time he revisits the web-page the Popup wont show.
Otherwise direct him to:
www.myapp.com/survey/
I think the best option here is to save this information in the database using your ASP.NET WebAPI2 REST APIs. In the moment that the end user clicks the survey you can also make an Api call which will save in the database info about user's action(this will probably be sth you can do for authenticated users). For not authenticated users you can just save that information in localStorage in the moment they are clicking the survey.

AngularJS routing /profile redirects to /profile/register when not logged in, browser history saves both routes

I'm facing a problem don't know how to solve. I would like to get some light here.
Given an AngularJS application that routes using the standard $routerProvider, and considering the fact that whenever an end user tries to access a private area he gets redirected to the register area, happens the following:
User just landed onto de application (didn't get logged in).
User goes to /profile
The application checks whether there is session info in the client or not.
The application redirects to /profile/register
User clicks on "Back" button of the browser and goes to /profile.
(Next step is number 3 again and again).
This happens because each time the application redirects using the $routerProvider, it pushes all routes in the browser history.
My question is, how can I jump the failed /profile access over the browser history? How can I tell the browser do not save this route under given conditions
like the user is logged in?
FAQ regarding history: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history
Supposing you're using the $location built-in service to redirect, you can use $location.replace() to replace the current history entry:
if (notLoggedIn) {
$location.url( "/profile/register" );
$location.replace();
}
Note that this will apply to current digest only, as noted in the API docs.

How to open an external URL in a modal from AngularJS app

I want to use OAuth in my AngularJS application, and to do so I need to take the user to the Twitter OAuth page so that they can grant access. I could do this inside my application, but I'd prefer not to redirect the user out of the context of the Angular app (i.e. don't reload the page) and so what I want to do is open the authorization page in a pop-up or modal window. The user completes the workflow in that window and when they close the modal, the access token is stored in my app, or in a cookie.
I am really struggling to figure out how to open this pop-up and populate it with the Twitter grant authorization page.
> Here is an example: http://plnkr.co/edit/NeMAj32daePMopWaffkw?p=info
If you could get an external website to open in that modal then I think I might be part-way there?
I don't believe that's possible. Even if you could embed the Twitter auth page inside a modal's iframe, the OAuth flow would ways force it to redirect. Knowing that a redirect is applied to the entire page (e.g. browser window/tab) and not only to the iframe, it would end up redirecting your entire page.
And there's also the phishing risk
Your only option is to open a new browser tab/window(popup).
More information about Twitter's OAuth flows here and here.

AngularJS and IE9 page refresh issue

My single page angularjs application seems to work fine in IE9+ until you edit an object and reload the page. If you modify a field (change Name from "You" to "Me") then press save the server gets the update and updates the database. If you then refresh the page the field has its original value (Name is "You"). Refreshing the page does not call the $routeProvider and does not go to the server.
None of this happens on Chrome, Firefox, Safari, or their mobile counterparts.
One of the biggest issues with IE is that it doesn't handle console.log unless the console is open and will break just about everything. Not sure if this is your problem, but always good to check.
My server side is an ASP.Net MVC app so I disabled caching.
Set the OutputCache attribute on the whole controller or certain actions
[OutputCache(Location = OutputCacheLocation.None)]
public class HomeController : Controller
{
//All actions in here won't be cached.
}
Used #KCD's answer from this question:
How do I add site-wide no-cache headers to an MVC 3 app

Resources