Thymeleaf cache and security in Spring Boot - spring

In my web app (Spring Boot + Spring Security + Thymeleaf) I disabled caching for security purposes:
spring.thymeleaf.cache=false
I can't remember where did I get this information from, or if it's even true.
I have a lot of images on my website and I'd like to cache them. What would you recommend?

Take a look at Spring Security – Cache Control Headers, it explains caching for ResponseEntity object, which can used to return an image in the form of a byte array.
This also shows a way of caching images specifically, although the post itself is from 2015, some parts can still be relevant.

Actually the spring.thymeleaf.cache property has nothing to do with security, but more with performance. If you disable the Thymeleaf cache, the templates will be automatically reloaded when they need to be parsed, it has to do with hot swapping your server-side templates.
This is helpful during development because you can instantly see changes to your templates. If not you would have to restart your application.
See the documentation on the Developer tools on what it's used for.
Spring as of version 4.x somewhere has several ways to implement static resource caching with versioning (cache busting mechanism). Assuming you are serving your images as static resources through Spring, you might want to look into these.
If the images themselves do not need to be secured, serving them up as static resources with caching applied like that should be enough.

Spring Security will automatically "cache bust" all requests, which is by design.
However for images that don't really need to be managed by Spring Security, you can disable it for specific resource directories, in your WebSecurityConfigurerAdapter (in this case the images directory would be in your ../resources/static directory).
#Override
public void configure(WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers(
"/images/**"
)
}
And the Spring Boot way is to add
spring.resources.cache-period=your value here in seconds
You would only want to turn off the Thymeleaf cache in development, when you want to do a hot-reload of a template.
Test it works with
curl -X GET -I https://your-site/images/foo.png
This will cache them at the browser level. If you needed to cache them at a server level, you could use a reverse proxy like nginx.

Related

Vaadin using SpringSecurity authentication

Currently learning Vaadin8+SpringBoot for Vaadin made me wanna forget about HTML for a while. Anyways, all is good for some CRUD operations until I mixed in SpringSecurity in the project. Well, I've been searching for days now and no solution could fit in well with the expected requirements.
Expected output:
Vaadin8+SpringBoot+SpringSecurity
All in one project/module/artifact
2 #SpringUI (MainUI = "", LoginUI = "/login")
Multiple #SpringViews contained by MainUI's ViewDisplay
Limitations:
No login.html (from the Vaadin's demo backery app)
No SpringMVC for login page
No vaadin4Spring dependency
Configurations done through annotations and not through XMLs
I know there's a way, I'm blocked how to progress on this. And if it's really not possible, need to understand as to why it isn't.
When you configure Spring Security, you need to allow anonymous access to the /login URL (either login.html if it is a non-vaadin form, or the login UI path if you want a separate UI for login). You also need to restrict access to the actual application UI. You also need to allow anonymous access to the static resources (i.e. /VAADIN/**).
The SecurityConfig in Bakery may give you a starting point. (Note: the starter or its parts cannot be redistributed as a code example or template)
There is a more detailed explanation here, though it only covers Vaadin and Spring Security integration (i.e. no spring-boot).

How to require SSL in some environments using Spring Boot 2.0.0.M4+

While upgrading my Spring Boot applications through the 2.0.0 milestone releases, I've noticed that starting in 2.0.0.M4 security.require-ssl and other security configuration options are gone. I didn't find any mention of deprecations or a new approach in the current docs so I dug around and found the GitHub issue where the work originated. I applaud the goal in the GitHub issue to:
significantly simplify security configuration in 2.0.
and am happy change my patterns to upgrade, but I'm a little stuck on how to require SSL in specific environments. I know I can accomplish a similar outcome in my WebSecurityConfigurerAdapter configuration using http.requiresChannel().anyRequest().requiresSecure() but I don't want to enable this setting in every environment I run my applications in (e.g. pre-production environments without a certificate, local development on localhost). I know I could put some conditional logic in my WebSecurityConfigurerAdapter configuration but I like to keep my Spring configurations "environment agnostic" and keep my environment specific configurations in properties files specific to a profile.
After these recent simplifying changes to Spring Boot's security configuration, what's a recommended approach to require SSL in some environments?
There are a few options depending on your setup.
Changing the RequestMatcher
If the only time you require HTTPS is in an environment with a custom header injected by a Proxy (i.e. X-Forwarded-* headers), you can do something like this:
http
.requiresChannel()
.requestMatchers( r -> r.getHeader("X-Forwarded-Proto") != null).requiresSecure()
.and()
// ...
The nice thing about this approach is that you do not need to do anything to turn HTTPS on or off. The downside is that there is a very minimal performance hit of comparing the headers. This performance hit should be negligible, but may not be aesthetically pleasing to some.
Conditional Configuration
Since this is Java Code you can always have a boolean flag that determines if you require HTTPS or not. For example, create a member variable and resolve it to Externalized Configuration with something like this:
#Value("${security.require_ssl}")
private boolean requireHttps;
Then use something like this:
if(this.requireHttps) {
http
.requiresChannel()
.anyRequest().requiresSecure();
}
http
// ...
This approach aligns nicely with Spring Boot 1.x approach and it does not suffer from the additional if statement in each request. However, it requires a property to be managed.
Profiles
As mentioned by Madhura you can also use #Profile. I find this approach is better suited if you have lots of differences between environments and not as ideal for something minor like determining if HTTPS is required. The problem with this approach when making a small change is you run into a lot of duplication.
You're absolutely right about adding your own WebSecurityConfigurerAdapter for customizing security configuration. To keep that configuration environment agnostic, you can add an #Profile so that it can be switched on and off depending on the active profile. If it is only the ssl configuration that is environment agnostic, and the rest of the security configuration is the same for all environments, you can add a WebSecurityConfigurerAdapter that only configures http.requiresChannel().anyRequest().requiresSecure() that has the #Profile on it and order it such that it is the first one that kicks in.

Is Spring Cache clusterable?

I've got an application that uses Spring Cache (Ehcache), but now we need to add a 2nd node (same application). Can the cache be shared between the nodes or each with their own instance but synched?
Or do I need to look at a different solution?
Thanks.
That depends on your cache implementation - not on Spring, which only provides an abstract caching API. You are using EhCache as your caching implementation, which comes with a Terracotta server for basic clustering support and is open source. See http://www.ehcache.org/documentation/3.1/clustered-cache.html#clustering-concepts for more details

Serve static content from folder outside of project

I'm currently developing a Java backend together with JHipster 3 and ran into a problem I don't seem to be able to solve very easily.
I would like to serve static assets – in this case images – from a folder outside of the project in addition to the default front-end generated by JHipster. As of default JHipster seems to serve static assets from one directory out of two depending on environment, as configured in main/java/config/WebConfigurer.java. I would like to point /public/** to a folder in my home catalogue but keep the /** mapping for the Angular front-end.
In general Spring projects you seem to be able to add other sources for static assets by extending WebMvcConfigurerAdapter and override the addResourceHandlers method, but that doesn't seem to have an effect in my case. Adding the #EnableWebMvc annotation breaks the default JHipster mapping for their front-end. If I don't add the annotation I don't even seem to reach handleRequest() in DefaultServletHttpRequestHandler which handles the mapping to the correct servlet.
I can't give any other information on the subject at the moment, but I'm hoping someone with knowledge on JHipster will see this and point me in the right direction.
Thanks in advance, Max.
All app servers have an option to provide additional locations for class path.
For example, Tomcat's property is 'common.loader' in conf/catalina.properties.
You can then use e.g. Spring's ClassPathResource to load a resource manually, or just use a construct like '#Value("classpath:abc.txt") Resource r' to inject something known in advance.

Spring Boot/Thymeleaf based large/mid scale application

We are starting out with Spring Boot, and looking for best practices
in implementing a large application. If you can provide links to any large/mid scale open source application
implemented using Spring Boot, that would be helpful.
Also we did research code generated by "JHipster" (jhipster.github.io/) project, which
definitely helps generating lot of boiler plate code like user management, transaction management, REST Services/ AngularJS based application.
The only problem is "JHipster" is AngularJS based. But in our case we
would like to go with "Thymeleaf" based UI.
If you can provide a link to framework/sample application similar to "JHipster",
but based on "Thymeleaf" based UI, that will also be very helpful.
Thanks
JHipster also supports Thymeleaf: by default it generates an AngularJS front-end, and this is its main goal, but you can also use Thymeleaf if you don't want a single Web page application.
If you have a look at the error pages, for example, they are done with Thymeleaf (as the 404 page can't be in the single Web page application, for obvious reasons)

Resources