I have searched for tutorials on this topics, but all of them are outdated. Could anyone provide to me any links, or samples about integrating Spring security into GWT?
First of all, you have to bear in mind that GWT application is turned into javascript running on client-side, so there is nothing you can really do about securing some resources out there. All sensitive information should be stored on server side (as in every other case, not only for GWT), so the right way is to think of Spring Security integration from the point of view of application services layer and integrating that security with communication protocol you use - in case of GWT it is request factory in most cases.
The solution is not very simple, but I could not do it in any better way... any refinement suggestions are welcome.
You need to start with creating GWT ServiceLayerDecorator that will connect the world of request factory with world of Spring. Overwrite createServiceInstance method taking name of spring service class to be invoked from ServiceName annotation value and return instance of this service (you need to obtain it from Spring ApplicationContext):
final Class<?> serviceClass = requestContext.getAnnotation(ServiceName.class).value();
return appContext.getBean(serviceClass);
Also, you need to override superclass invoke(Method, Object...) method in order to catch all thrown runtime exceptions.
Caught exception cause should be analyzed, if it's an instance of Spring Security AccessDeniedException. If so, exception cause should be rethrown. In such case, GWT will not serialize exception into string, but rethrow it again, thus, dispatcher servlet can handle it by setting appropriate HTTP response status code. All other types of exceptions will be serialized by GWT into String.
Actually, you could catch only GWT ReportableException, but unfortunately it has package access modifier (heh... GWT is not so easily extensible). Catching all runtime exceptions is much more safe (althouth not very elegant, we have no choice) - if GWT implementation change, this code will still work fine.
Now you need to plug in your decorator. You can do it easily by extending request factory servlet and defining your's servlet constructor as follows:
public MyRequestFactoryServlet() {
this(new DefaultExceptionHandler(), new SpringServiceLayerDecorator());
}
The last thing - you need to do a dirty hack and overwrite request factory servlet doPost method changing the way how it handles exceptions - by default, exception is serialized into string and server sends 500 status code. Not all exceptions should result in 500 s.c - for example security exceptions should result in unauthorized status code. So what you need to do is to overwrite exception handling mechanism in the following way:
catch (RuntimeException e) {
if (e instanceof AccessDeniedException) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
} else {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
LOG.log(Level.SEVERE, "Unexpected error", e);
}
}
Instead of extending classes, you can try to use some 'around' aspects - it is cleaner solution in this case.
That's it! Now you can annotate your application services layer as usual with Spring Security annotations (#Secured and so forth).
I know - it's all complicated, but Google's request factory is hardly extendable. Guys did a great work about communication protocol, but design of this library is just terrible. Of course the client-side code has some limitations (it is compiled to java script), but server-side code could be designed much better...
Related
Roman Elizov has a great blog post on how to use exceptions with Kotlin. He emphasizes that catching exceptions in kotlin is usually code smell.
But does that mean that I should be able to throw exceptions freely in my Spring application if I am using application level exception handlers?
More specifically let's say I have function that looks up an item in the database, and a controller that calls this service. If the item is not in the database, should I return a nullable from the service or should I throw an exception? (The controller doesn't have to try/catch the exception because all applications are handled at framework level)
It depends on your use case and context. But generally I would say that you should throw an exception annotated with #ResponseStatus(HttpStatus.NOT_FOUND).
I've a MQ Spring Boot PaaS application where I need to implement exception handling via a common exception handler class (GlobalExceptionHandler). My PaaS application receives message from a source queue, perform some database operations via spring jpa and write the response back to a destination queue.
I need to handle all the database RuntimeException, custom business exceptions and other checked exceptions via GlobalExceptionHandler class.
My GlobalExceptionHandler will have handlers (method) defined for every exception. In my handler, I will be logging the exception first and then I will be creating a [error code, desc] and then I need to return it back to main flow.
I do not have any controller in my application. So I think, I can't use #ControllerAdvice. Currently I'm using spring AOP #AfterThrowing as below but I'm not able to return the [code, desc] from handlers.
#AfterThrowing(pointcut = "execution(* com.abc.xyz.service..*(..)) ",
throwing = "dataNotFoundException")
public void handleDataNotFoundException(DataNotFoundException dataNotFoundException) {
LOGGER.info("Info : " + dataNotFoundException.getMessage());
// code, desc need to create here and send it back to calling place.
// I need to change the return type here from void.
}
Can anyone please guide me in implementing exception handling here.
As I explained here, #AfterThrowing cannot modify return values or otherwise change the execution flow of your epplication. You cannot even catch the exception there. You need to use an #Around advice instead.
I suggest you read some documentation first and then ask more follow-up questions.
I am creating a Spring Boot web application, but i am confused why people use Global Exception handlers(#ControllerAdvice) when there is Error Page Registrar which is neater and more explicit. Please can someone explain more and is it possible to call an Error page registrar from a global Exception Handler Class( class annoted with #ControllerAdvice, with an #Exceptionhandler method).
As Brian answer, I think you can do this. I got a sample to prove this one in here if you still need to refer: https://github.com/kennytai/SampleSpringbootExceptionHandler
At this sample, I use the #ControllerAdvice in class GlobalExceptionHandler to manage all exceptions from TestController.
Hope this help.
It's actually the opposite the error pages mechanism in Spring Boot is the global one; it's catching all exceptions unhandled by the application. Note that in a Servlet environment, it's even dispatching the request back into the container on the /error path.
You're right though, this mechanism is really powerful and you can achieve a lot with it.
The other exception handling mechanisms you're mentioning are provided by Spring MVC itself. They're executed during the handling of the request and don't require an additional dispatch to the container. In some cases, they can be more limited because they offer less features than the full ErrorController (which is an MVC Controller).
But unlike error pages, you can configure those to focus on only specific errors:
You can declare an #ExceptionHandler within a Controller and specify the type of Exception you'd like to handle
You can configure the #ControllerAdvice annotation to only apply to specific packages, Controllers extending a specific interface or annotated with a specific annotation
I'd say the latter are quite useful when you want to deal with business exceptions at the controller level. You can do that with error pages, but you might end up with a single error controller dealing with too many things.
I am using Spring Hibernate integration in my application and DAO classes are extending HibernateDaoSupport.
Suppose I save some object using the code
getHibernateTemplate().save(object);
As Spring Hibernate integration doesn't mandate to write try-catch block, but suppose if any exception is thwron while saving that object.
Then what is the best way to handle it? I means should I catch it in the service layer and wrap it in some user defined excpetions.
Do I need to write try-catch in DAO layer method itself in case I want to log which method in DAO throws exception?
I have never used HibernateDaoSupport or Hibernate Template before so ignorant about exception handling. Please provide me your valuable inputs
The idea behind Spring using RuntimeException is that generally there are different types of exception:
Exceptions that you want to recover from (such as a DuplicateKeyException if a record that you're trying to insert already exists or the more general DataIntegrityViolationException if there was a DB constraint that was violated as a result of user input)
Exceptions that you can't recover from (the database is down)
For the first case, you may well handle the exception (either through a custom business exception, so that the view layer can redirect to the input page and provide a meaningful message)
For the second case, it would be easier to let the exception bubble up and have it handled by a generic exception handler that then displays a generic error page to the user. For this scenario it doesn't make sense to wrap the exception in a custom exception as you won't be able to recover. A blown up DB tends to be fatal.
So what I would do:
try {
getHibernateTemplate().save(object);
} catch (DataIntegrityViolationException dive) {
throw new BusinessValidationException(dive, "You've got the data wrong");
}
Spring exception hierarchy is well documented.
Usually you can't do much if you have a data access exception, because in the working system this may be caused by the shortage of diskspace on the DB server, or network connection problems etc.
Such exceptions are usually need to be logged and investigated as soon as possible.
There some recoverable errors, they can be handled with spring exception hierarchy, but imho most of them should be avoided during the developing phase, so your web server should validate as many things as possible, before it goes to the db.
If you want to set the exception logging see the similar questions:
Exception handler in Spring MVC
Spring MVC Best Practice Handling Unrecoverable Exceptions In Controller
From a jsp is thrown a NullPointerException for example using <% null.toString(); %>
This exception is not handled by the HandlerExceptionResolver, but thrown to the web container(tomcat) and converted into a code 500 error.
How can I configure spring to get that error in my HandlerExceptionResolver ?
Details:
Spring can be configured to handle exceptions thrown inside Controllers, but not exceptions thrown by view.
Of course i can resolve the NullPointerException, but i want to design a solution that will gracefully resolve any possible problem on the web application in order to display a user friendly message to the user.
See the HandlerInterceptor interface instead. You'll want the afterCompletion method. You can then intercept the response and then set the appropriate header information to redirect to a container-configured error web page. You're right that Spring doesn't have this functionality, this is going to have to be specified by the web.xml which determines which codes map to which pages.
I have not worked with this particular bit of the spring framework, but the docs say
"Interface to be implemented by objects than can resolve exceptions thrown during handler mapping or execution, in the typical case to error views. Implementors are typically registered as beans in the application context.
Error views are analogous to the error page JSPs, but can be used with any kind of exception including any checked exception, with potentially fine-granular mappings for specific handlers."
so I'd imagine that given that NullPointer extends RuntimeException the framework isn't designed to catch it. Is there a reason the exception(s) can't be handled in the controller directly?