Spring security access denied exception - spring-security

I have a web page which is connected to a spring #component class.
There is a method that requires roles(by spring annotation #Secured('ROLE_USER')) and it is called with a button.
My problem is when i click the button without having the required role,it causes an error named access denied exception.I want to redirect the page to error a page when this occurs. I tried access-denied-handler on application context but it did not work.
By the way, is #component tag enough or should i add something else such as #controller?

Just add an error page to your web.xml like this
<error-page>
<error-code>403</error-code>
<location>/pages/accessDenied.jsp</location>
</error-page>
If you want to set error page using accessDeniedHandler take a look at this How to redirect to access-denied-page with spring security

Related

ELMAH IController factory not found - Right way to redirect to Error page - MVC

Am trying to use ELMAH with MVC4 and configured using NUGET Package for MVC.
It handles all the exceptions happening in my code and am logging it to SQL Server.
Using the Ajax Error function am handling AJAX Exceptions(500) Error too. Everything works fine and redirected Error page overriding OnException in Filter Config
But if the user changes the URL and and if the controller doesnt exist am getting Error and not redirected to the Error page.
Ex:
sitename/test -- Correct URL
sitename/tst ---- Getting Server Error instead redirecting to Error page
What is the correct way to handle 404 using ELMAH and redirecting to friendly 404 page in MVC.
I tried changing the Custom Error with 404 in web.config but it didn't worked as expected.
By default all Errors other than 404 am re directing to Error page
Am trying to redirect to friendly 404 page rather than server error page.
Any useful links or code will be helpful .Thanks
============================================
Update web.config
<customErrors mode="On">
<error statusCode="500" redirect="/Views/Shared/Error.cshtml"/>
<error statusCode="404" redirect="/Views/Shared/ErrorNotFound.cshtml"/>
</customErrors>
In ASP.NET MVC, your URL does not represent the View you are displaying. It is the Controller Action. You cannot navigate to a View.
For example, the url ~/Home/Index, does not point to Views/Home/Index.cshtml. It points to the Index method of Controllers/HomeController. This method then renders the Index.cshtml view and returns the result.
So first, you need to create an ErrorController. Then, you need to move your Error Views into a matching Error folder. Now add action methods for Error and ErrorNotFound to your ErrorController, and have them return the correct View.
Finally, change your web.config redirect URL's to ~/Error/ErrorNotFound.
Using this method, you will probably want to change the names of the Controller Actions, and their respective Views to remove the duplicated work Error.

ViewExpiredException - why different behaviour?

I have a JSF 2 application and configured the following in web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/error.html</location>
</error-page>
For testing purposes I have the following code in a #SessionScoped class within an init Method annotated with #PostConstruct in order to let the session quickly expire:
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
HttpSession session = (HttpSession) ec.getSession(false);
session.setMaxInactiveInterval(5);
Now, when I have an h:commandButton with outcome = "somepage.jsf" then a click after the 5s will redirect to the error page.
When I instead call some bean action or putting the page name in action on the very same button using the action attribute , I see the ViewExpiredException in the server's log, but no redirection occurs.
Why is that so? And how to generally redirect to another page no matter which action took place after the session expires?
The behaviour is different because an asynchronous (ajax) request is been sent. Ajax requests require a special XML response. Exceptions on ajax requests needs to be handled by either the jsf.ajax.addOnError handler in JavaScript or a custom ExceptionHandler.
By default they have namely no single form of helpful feedback in the client side. Only in Mojarra with project stage set to Development you'll see a bare JavaScript alert message with the exception message. But that's it. There is no single form of feedback in Production stage.
With a custom ExceptionHandler you would be able to simulate exactly the same form of feedback as in synchronous requests. You could parse the web.xml to find the proper error page location, create a new UIViewRoot around it and force JSF to set ajax rendering to #all. Since that's after all relatively quite some work, the JSF utility library OmniFaces provides exactly such an exception handler out the box in flavor of FullAjaxExceptionHandler. You can find the showcase page here.

Error page defined in web.xml is embedded in partially rendered JSF page

I have the following defined in web.xml:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/shared/errors/DefaultErrorPage.xhtml</location>
</error-page>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/shared/errors/ViewExpired.xhtml</location>
</error-page>
I'm also using the FullAjaxExceptionHandler from Omnifaces in faces-config.xml:
<factory>
<exception-handler-factory>
org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory
</exception-handler-factory>
</factory>
The FullAjaxExceptionHandler is working fine for ajax calls, but when I hit a page directly and there is an error, it starts rendering the page I was trying to go to, but it doesn't finish, and then the error page defined in web.xml is rendered, which results in the error page being embedded after a partially rendered page.
(I'm using Glassfish 3.1.1 which has Mojarra JSF 2.1.3) Edit: now using Glassfish 3.1.2.2 and JSF 2.1.11
Edit: Discovered the following:
The page where the error is happening is using templates (<ui:composition template="/shared/shared/commonLayout.xhtml">) If I change it so that the page is no longer using the template, and then just add in all of the code from the template then it works fine.
This will happen when the response is already committed before the exception is been thrown. The response will be committed when ServletOutputStream#flush() has deep under the JSF covers explicitly been invoked in some way, which is more than often only when the response buffer (defaults usually to 2KB in most containers) has been overflowed. A committed response is a point of no return. The server cannot take the already-sent bytes back from the client. The server has basically 2 options:
Leave the response as is and log the exception to the server log only.
Try writing the error page to the response anyway.
Your Glassfish setup apparently chooses the 2nd way. None of them is perfect. The client would still end up with a halfbaked HTML response and whatever it would end up to look like to the enduser depends on how the webbrowser can do its best in interpreting and presenting the so far obtained HTML.
You, as JSF developer, can however use several approaches to avoid this from happening. In first place, why exactly is that exception been thrown during rendering the response? Doesn't that actually indicate a bug in your own code? Wouldn't you better perform the exception-sensitive business job before rendering the response? You could use among others <f:event type="preRenderView"> for this.
<f:event type="preRenderView" listener="#{bean.init}" />
If that's really not an option for some reason, you could consider increasing the response buffer size to above the size of the largest HTML response, so that the response won't be auto-flushed before the exception occurs. You can do that by the following context parameter which assumes that every HTML response fits within the 100KB limit:
<context-param>
<param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
<param-value>102400</param-value><!-- 100KB -->
</context-param>

JSF wrong redirection when catching ViewExpiredException

So I have a ViewExpiredException Handler and works fine.
Now, when I launch the web-app my URL looks like www.myApp.com/TestFaces/ and this presents the first page which is the login page.
If for any reason I leave the page at login, and the View expires the app catches the ViewExpiredException and sends me to a page "ViewExpired" BUT the URL keeps the same www.myApp.com/TestFaces/. On that "ViewExpired" page I have a commandLink to return to the login page which in the value attrib I put "index.xhtml" BUT it does not send me to login page because on there's no page on www.myApp.com/TestFaces/index.xhtml but in www.myApp.com/TestFaces/faces/index.xhtml
So the questions are:
Why if I'm at login page am I getting the ViewExpiredException? is it because of ajax?
How or Where can I make the commandLink really sends me to index.xhtml?
This is only happening when the View expires in login page, in other pages from my app it works really great.
Thanks in advance !
Why if I'm at login page am I getting the ViewExpiredException? is it because of ajax?
You will get this exception when you invoke a POST request on a view which does not exist in session anymore. This can for example happen when you keep the page open for too long that the session has expired in the server side, or when you're getting the login page from the browser cache instead of straight from the server. For more detail, see also our ViewExpiredException tag info page. All JSF ajax requests also accounts in this as they also use POST.
How or Where can I make the commandLink really sends me to index.xhtml?
Make use of implicit navigation. This way JSF will append the proper FacesServlet mapping.
public String goToIndexPage() {
return "index";
}
or
<h:commandLink value="Go to index page" action="index" />
or, better, when you don't need to invoke any business logic at all:
<h:link value="Go to index page" outcome="index" />
See also:
Check if session exists JSF
When should I use h:outputLink instead of h:commandLink?

sitemesh + spring security: show logged in user in main decorator page!

I want to show logged in user in main decorator page.
i use :
<decorator:usePage id="myPage"/>
Logged in as:<%= myPage.getRequest().getUserPrincipal().getName()%>
<decorator:body/>
but not work!
You need to place the SiteMesh filter-mapping below the Spring Security filter mapping.
See: Spring security tags in sitemesh decorator
Haven't worked with SiteMesh for quite some time, but why aren't you using the implicit request object instead (I assume your pages are written in JSP, right?)
<%= request.getUserPrincipal().getName() %>
And what's exactly not working? Is an exception getting thrown?

Resources