When I threw a BadCredentialsException from AbstractUserDetailsAuthenticationProvider's concrete class with a message, it has been handled by spring and appropriate message present in the default failure jsp is displayed.
But when AuthenticationServiceException is thrown from same class, spring is not able to handle it rather is displaying a stack trace. I observe that in this case the spring is not able to redirect to the default failure jsp.
Both BadCredentialsException and AuthenticationServiceException are subclasses of AuthenticationException, then why is spring security handling in different ways?
Is there any place where his configurain needs to be set up?
Is there any specific reason why AuthenticationServiceException is not handled?
Related
I am running Mojarra 2.2.0.
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
The managed bean action method is-
public void action() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
.getExternalContext().getSession(false);
System.out.println(session.getId()); // not null for stateful views
}
For stateless views session.getId() throws NPE
For views which are not stateless-
Firing a GET request, there is JSESSIONID=340041C96D5AA446D761C3602F54A76D
I read it here that-
For client side state saving mechanism, JSF won't create the session
and will store the view state in a hidden input field with the name
javax.faces.ViewState in the form whenever necessary.
Further, it's mentioned here that
JSF will indeed autocreate the session because the JSF view state has
to be stored over there. If you set the JSF state saving method to
client instead of server, then it won't be stored in session and hence
no session needs to be created
I think the above line is a source for trouble for me.
If you set the JSF state saving method to client instead of server,
then it won't be stored in session // FULLY AGREED
and
hence no session needs to be created. // This confuses because for
client side saving mechanism, a session id gets generated by the
servlet container & hence there is a session associated with the
request.
In reference to the discussion which I had with BalusC in this question,
I created a HttpSessionListener-
#WebListener
public class MyHttpSessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent event) {
Thread.dumpStack();
}
public void sessionDestroyed(HttpSessionEvent event) {
}
}
See below attached screenshots(these 2 screenshots are for version 2.0.3, there must have been an old bug due to which the session was getting created)-
Libraby (Mojarra 2.2.0)-
When does JSF creates a session
Eaiest way to naildown this is creating a HttpSessionListener, putting a debug breakpoint on sessionCreated() method and inspecting the call stack who needed to get the session for the first time (and thus implicitly needs to create it).
In below example you will see a chain of getSession() calls in the call stack. You will see that FaceletViewHandlingStrategy.renderView() method is the one calling it for the first time.
After you click on FaceletViewHandlingStrategy.renderView() line in debugger's call stack, you will get into its source code (Maven will load source code automatically, otherwise you need to manually attach it).
You see, when server side state saving is enabled and the view to render is not transient (stateless), then JSF will implicitly create the session, just to ensure it's created on time in order to save the view (if the session was created later, e.g. during render response phase, you would otherwise risk exceptions like this Adding <h:form> causes java.lang.IllegalStateException: Cannot create a session after the response has been committed).
You'll in the source code also immediately see that when the state saving method is set to client, or when the view is stateless as in <f:view transient="true">, then JSF won't anymore implicitly create the session. Older JSF versions may do that as you figured, but this is to be accounted as a bug and ought to be fixed in a newer version.
If you would like to ensure statelessness and avoid accidental/unforeseen session creation, then you could just throw new IllegalStateException() inside sessionCreated() method. When that happens, you just have to look in call stack who's responsible for creating the session and then fix/change the code to not do that anymore.
what does it puts in a session map?
Under the covers, ExternalContext#getSessionMap() delegates to HttpSession#setAttribute()/getAttribute()/removeAttribute(). You can listen on those methods using a HttpSessionAttributeListener.
In below example you will see that ViewScopeContextManager.getContextMap() line calls SessionMap#put() method in order to put something in the session map. When you unfold the event argument, you will see the session attribute name and value, which is com.sun.faces.application.view.activeViewContexts and an empty ConcurrentHashMap respectively.
Indeed, I was using a #Named #ViewScoped which was referenced by an value expression on the particular page (you see EL resolver and Weld resolver further down in call stack). When you click ViewScopeContextManager.getContextMap() line in call stack, you'll see that it was just preparing a map in session scope in order to store view scoped beans.
That's just one example. There are more things which could be stored in the session. Using a debugger this way and inspecting the associated source code will tell a lot about the Why.
I want to be informed when uncaught exceptions occur in my Grails 2.2.4 application. Log4j has an SMTPAppender doing something similar, but only based on a specific log level. In my application there are already a lot of log entries in all available log levels, so sending email on ERROR or FATAL is not really an option because it would also contain non-exception entries.
Filtering uncaught exceptions in Grails is quite easy, I just redirect them to a specific controller and handle it there:
static mappings = {
[...]
"500"(controller: "errors", action: "serverError")
}
My plan was to introduce my own log level and use it only for uncaught exceptions. Documentation suggests this:
final Level EXCEPTION = Level.forName("EXCEPTION", 50);
logger.log(EXCEPTION, "uncaught exception", e);
But I don't know how to use this in Grails with the injected log object. It only supports the base options like log.error('foo',e). Grails documentation says how to add custom appenders, but nothing about custom levels (or did I miss it?!)
Any suggestions?
Grails uses Slf4j and Commons Logging to abstract the logger implementation and allow changing from Log4j to another framework without having to edit every file with a logger. Instead, the wrapper library gets the correct implementation instance based on the requested logger name and what's available from the native API. If you change implementations, the wrapper loggers work the same way as far as your app code is concerned, but they call different implementation loggers to do the actual logging.
But there's no standard between implementations for configuration, so internal Grails startup code works directly with the API to configure loggers, appenders, levels, etc. You can do the same - use the traditional Log4j logger access code to get an instance by logger name, using the same one as the preconfigured logger Grails wired up. I can never remember the naming convention for loggers in artifacts, so I cheat and add a line of code
println log.name
in a method that I know runs, and call that method indirectly via whatever controller action can get there. So for example, if I want to know the logger of FractalService, put that code in its graphJuliaSet method and call the controller action that graphs Julia Sets using this service.
Log4j loggers are singletons, if you access the logger and change it, that will affect all future calls.
So that logger is available via something like:
String name = ... // the name from the println above
Logger logger = Logger.getLogger(name)
I'm currently using Spring Data with Neo4j and have subclassed the SpringRestGraphDatabase to allow the registration of specific transaction event handlers.
I call the registerTransactionEventHandler method to do so. Unfortunately I always get the following exception:
Caused by: java.lang.UnsupportedOperationException: null
at org.neo4j.rest.graphdb.AbstractRemoteDatabase.registerTransactionEventHandler(AbstractRemoteDatabase.java:52) ~[neo4j-rest-graphdb-1.6.jar:1.6]
at org.neo4j.rest.graphdb.RestGraphDatabase.registerTransactionEventHandler(RestGraphDatabase.java:28) ~[neo4j-rest-graphdb-1.6.jar:1.6]
By looking closely at the AbstractRemote I see that it always throws an exception:
public <T> TransactionEventHandler<T> registerTransactionEventHandler( TransactionEventHandler<T> tTransactionEventHandler ) {
throw new UnsupportedOperationException();
}
The RestGraphDatabase doesn't provide an implementation for the register method hence the exception. I'm not sure what alternatives to use, especially as I'm extending SpringRestGraphDatabase.
Is there a cleaner alternative?
(I'm using v2.1.0.M1)
Yeah,
the exposure of these handlers would be very costly over the network. Depending on what you want to do, I would suggest writing a custom plugin to expose your operations and register what you need via a REST endpoint, see http://docs.neo4j.org/chunked/snapshot/server-plugins.html
I'm using Spring Secuirty 3 with ACL module. I'm securing the methods with #PreAuthentication annotations using a custom PermissionEvaluator. Its working fine, however every time the PermissionEvaluator returns an ACCESS_DENIED an AccessDeniedException is thrown at some point and this stops the application execution. The desired behaivore will be that when the PermissionEvaluator returns and ACCESS_DENIED, the secured method call is only prevented (skipped) and the rest of the application keeps running normally. Does anyone have an idea on how to achieve this?
If you wrap each call where you want this to happen in a try...catch, you can get this behavior. Basically, since it's an exception, any normal exception handling will apply to it. If your application can handle that exception and continue normally, then do exactly that!
Here's an example of what I mean:
// The 1st method that could be denied but you want to continue execution after
try {
// Call method A that will throw the exception
} catch (/*The exception you expect to be thrown and want to continue after*/){}
// The 2nd method that could be denied but you want to continue execution after
try {
// Call method B that will throw the exception
} catch (/*The exception you expect to be thrown and want to continue after*/){}
etc.
Yes, it does add a lot of overhead to calling those methods, but it is a fairly simple way of allowing execution to continue after an exception is raised.
I would also argue that it is also more correct, since the calling code does know how to deal with those exceptions. This also doesn't require any additional Spring configuration, which means that the code behavior remains closer to the default and does not rely on external configurations to determine it's behavior.
Hi
I am new to Spring Security 3 and was trying out #PostFilter on a method declared in an Interface but the returned Collection is not getting filtered.
Here is the code:
public interface IProductService {
#PostFilter("(!filterObject.customersOnly) or (filterObject.customersOnly and hasRole('ROLE_USER'))")
Collection<Category> getCategories();
}
customerOnly is a boolean attribute in a domain object Category.
I've added the following element on xyz-security.xml:
<global-method-security pre-post-annotations="enabled" />
Could someone help me understand what am i missing?
Thanks
The typical causes for this are:
AspectJ and/or CGLIB JARs are not in your classpath.
You have the annotation on an interface OR on a class (review the Spring AOP docs to determine which is supported for which AOP implementation).
You have added the Spring Security configuration to a different ApplicationContext than where you have declared your secured beans (for example, you are trying to secure a bean in your *-servlet.xml file, when your Spring Security configuration is declared by the ContextLoaderListener).
You have removed or altered the declaration so that the annotated bean is not processed by the same ApplicationContext where Spring Security is configured.
If none of these suggestions applies, please enable DEBUG logging and watch application startup to see if the bean annotation is processed at all.
As an aside, I have had many readers report similar flavors of this problem - the source code for this sample does work, but in all cases it has been true that readers have subsequently changed one of the above 4 items, causing the sample code to "break" ;)