Should You Use Spring Boot in Your Next Project?

Tweet about this on Twitter113Share on Facebook25Share on Google+20Share on LinkedIn42Share on Reddit0Email this to someone

The State of Spring

Most of my professional Java projects over the past decade have been based on Spring or JEE.  Both platforms are growing a bit long in the tooth, and suffer from different problems.  JEE has changed quite dramatically over the years, but is still judged on issues deprecated since EJB 2.x.  A lot of people still refer to JEE as “J2EE”, even though the name change was 8 years ago!

spring-logoSpring has grown as well, but that community seems loathe to deprecate anything.  Although a modern Spring application can be quite contemporary and clean, most applications that I see are still riddled with XML config and outdated design choices.  Spring may have been arguably superior to JEE in 2006, but the problem is that many developers haven’t kept up-to-date with either platform since then.

Spring and JEE are still the gold standards for large-scale, large-team enterprise Java development.  However, as the Java community matures, it hasn’t maintained the same innovation or excitement it had a decade ago.  Which perhaps is an inevitable part of maturity.

Other languages and frameworks have therefore emerged to challenge the status quo.  Java was probably the most popular language for personal projects when I was in undergrad, but younger developers today seem to devote more personal focus on Python, JavaScript, and the revolving door of fad languages discussed on Hacker News.  The most influential web framework of the previous decade was clearly Rails, and the Ruby-based Sinatra has spawned a proliferation of micro-frameworks over the past five years.

Groovy and Grails, the Java world’s initial answer to Ruby and Rails, can now be found even in conservative enterprise shops.  Newer JVM-based frameworks go much further.  Rather than merely slapping an easy wrapper around JEE and Spring API’s, the Play framework starts from scratch… discarding even such fundamentals as the Java servlet model.  Vert.x is inspired by the Node.js style, and targets Java developers interested in experimenting with other languages.

The bottom line is that Spring hasn’t been seen as an exciting source of innovation for some time now.  Developers still use it, especially for legacy applications… but increasingly they use it in greenfield development because they have to, not because they enthusiastically choose to.  I can’t remember the last time I spoke with a developer using Spring in a personal project, rather than Play or some other platform altogether.

The Need for a Better Bootstrap

spring-projectsThis is a shame, because Spring is an incredibly powerful tool… once you get it setupSpring Data JPA gives you easy relational database management without writing DAO classes… once you get it setup.  Other libraries in the Spring Data portfolio provide similar hooks into major NoSQL datastores… once you get it setup.  There is config-driven access to AMQP message queues, enterprise integration, and robust batch processing with little or no code… once you get it setup.  You can easily connect with API’s for the major social networks, in a web application or from an Android app… once you get it setup.  Then there’s Spring Security… but let’s not even talk about setting up Spring Security!

Bootstrapping a Spring application can be painful.  Part of this is due to the sheer size and growth rate of the portfolio.  Is it really worth using Spring Data JPA, if you’ve already invested your time learning the core JdbcTemplate and Hibernate/JPA wrappers?  What is the difference between Spring Data REST and Spring HATEOAS?

The other complicating factor is that Spring seldom deprecates anything, and offers little opinion or guidance.  So if you search online for examples, or help troubleshooting a problem, older links with older approaches remain at the top of the search results.  This is a large part of why XML-based config is still so common, even though annotation-based config is easier to maintain.  Instead of using a clean template system like Thymeleaf or Velocity, most Spring apps still use JSP with JSTL despite this being deprecated and stagnant.  There is something to said for familiarity, but escaping cruft is why Spring rose to challenge JEE in the first place.

Innovative drive never ceased among SpringSource developers themselves.  Five years ago, they introduced Spring Roo, a rapid development system inspired by the Rails command line tool.  Roo allows developers to quickly bootstrap a new Spring application, and create elements such as web controllers or JPA entities through a comand-line console.

However, for non-trivial use, the learning curve is almost as steep as building an application by hand.  Perhaps even more so, since you still need to understand the underlying elements.  Many developers were put off by the annotations and AspectJ files that Roo litters throughout your codebase to perform its magic.  Although Roo is advertised as being easy to remove once you’re up and running, the reality is that removal is a major and tedious undertaking.  Moreover, once you do convert the AspectJ stuff to plain Java, you lose the ability to use the magic command line tool.  Roo is an interesting system created by talented developers, but never really caught on.

Along Comes Spring Boot

spring-boot-logoSpring Boot is the next-generation attempt at easy Spring setup.  There is an optional command-line tool of sorts, for testing small prototypes written in Groovy.  However, Spring Boot is not an automatic code generation tool.  Rather, it’s essentially a plugin for your build system (Maven and Gradle are supported).

One one level, the plugin provides facilities for testing and deploying a Spring application.  With the command:  mvn spring-boot:run, Maven launches your application on port 8080.  This is similar to the Maven Jetty plugin, which has become a popular way to test Java web applications in other frameworks.  Also, Spring Boot lets you package up an application in a standalone JAR file, with a full Tomcat server embedded.  This clearly takes a page from the Play framework’s deployment model (although you can still build traditional WAR files too).

Spring Boot’s main benefit, however, is configuring resources based on what it finds in your classpath.  If your Maven POM includes JPA dependencies and a PostgreSQL driver, then Spring Boot will setup a persistence unit based on PostgreSQL.  If you’ve added a web dependency, then you get Spring MVC configured with sensible defaults.

Speaking of sensible defaults, Spring Boot actually has opinions!  You may not always agree with the defaults, but at least it offers defaults. If you want persistence, but don’t specify anything else, then Spring Boot configures Hibernate as a JPA provider with an HSQLDB database.  If you’re bootstraping a web application, but don’t specify anything else, then Spring Boot configures a view resolver for the Thymeleaf template system.

Spring Boot doesn’t actually generate code, but bootstrapping a new application is as simple as creating a POM file with these elements:

...
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.0.0.RC3</version>
</parent>
...
<properties>
	<start-class>com.mypackage.Application</start-class>
	<java.version>1.7</java.version>
</properties>
...
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
	</dependency>
	<dependency>
		<groupId>com.h2database</groupId>
		<artifactId>h2</artifactId>
		<version>1.3.174</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>
...
<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>
...

… and a main Java class like this:

@Configuration
@EnableAutoConfiguration
@ComponentScan
@PropertySource("classpath:application.properties")
public class Application {

    @Bean
    MyCustomService myCustomService() {
        return new MyCustomService("");
    }

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);

        System.out.println("Let's inspect the beans provided by Spring Boot:");

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }
    }

}

For the most part, changing a default involves changing the classpath.  Notice in the POM snippet above that I’ve added a dependency on the H2 database.  Spring Boot will see this, and configure my JPA persistence unit for H2 rather than the HSQLDB default.  If you wanted to use Jetty instead of Tomcat as the embedded server, then just add a Jetty dependency.

Opinionated defaults are a good thing, though.  Newer developers can get up and running quickly, and then replace defaults as they learn about other options… rather than having to research all the options for everything before they can even get started.

Ready for Prime Time?

Spring Boot is in “incubation”, and at the time of this writing is still one or two release candidates away from version 1.0.0.  It won’t be meant for production until it’s promoted to full project status, and so it’s not fair to judge whether you should be using Spring Boot in production today.  However, it is fair to look at the velocity of its progress so far, and consider whether it’s worth exploring for personal applications, or professional projects that won’t go to production for awhile.

I’ve been exploring Spring Boot for about a month now in a personal project, a web application for tracking diet and exercise (source code on GitHub).  Spring Boot has leaped through two significant version updates during that brief time.  Although I’ve only had to make minor changes with each update, I have had to make changes both times.

Kudos to the Spring Boot team for providing a GitHub repo with around two-dozen sample projects.  However, the examples lag behind the current version of Spring Boot.  Moreover, each sample showcases a very specific feature, in a “Hello world” manner.  It’s been surprisingly tricky to combine multiple features into one non-trivial app (although this has improved over the past month).  The core Spring Framework offers an 800-page developer’s guide, of higher quality than most commercial books.  Spring Boot documentation, however, consists of about a dozen pages of random notes thrown together.

With the current lack of documentation, it’s often unclear which defaults Spring Boot is using… much less how to tweak or replace them.  Also, while I chided many developers at the beginning of this article for not keeping up with the times, the truth is that some of Spring Boot’s defaults expose me as guilty too.  I was not previously familiar with Thymeleaf, the default view template system.  My impression so far is that it has a steeper learning curve than Velocity or FreeMarker.  Spring Boot’s opinions give valuable guidance to newer developers just starting out, but may frustrate seasoned developers who are resistant to change.

Conclusion

All of this being said, I think that Spring Boot is the real deal.  I would not try to use it for a professional project in production today, but I think it’s worth exploring now for personal development and side projects.  When Spring Boot graduates to full project status and solidifies, and when it gets the same level of documentation as other Spring projects, then I believe it will make little sense to continue bootstrapping Spring projects manually.  It will also reduce the complexity and cruft that makes newer frameworks so tempting in comparison.

What’s more, Spring Boot really guides the way toward good modern Spring development practices.  If you have been sticking with familiar approaches, and not keeping up with the times because of how complex bootstrapping new Spring applications can be, then Spring Boot provides a great benefit as a teaching tool.  Even if you’re not using Spring Boot in production just yet, it will improve your Spring knowledge and skills right now.

  • Greg Turnquist

    Don’t forget about all the guides at http://spring.io/guides, a huge portion which use Spring Boot to reduce complexity.

    • http://steveperkins.net/ Steve Perkins

      Thanks for the heads-up, Greg! I’ve browsed the “Guides” page before (the new “spring.io” site is fantastic, btw)… but it’s been a little while, so I wasn’t aware that they were mixing Spring Boot into the examples.

      To me, Roo always felt like a “separate” entity, off to the side. It would be great to see Spring Boot more deeply intertwined with the rest of the Spring portfolio over time. I think Boot is great for lowering the barrier to entry of other Spring projects. Professionally, I have only worked extensively with a handful of portfolio components (e.g. core, JPA, AMQP, Integration, and Batch). Since getting into Boot, I’ve used it to explore several other projects that I might not put the time into exploring otherwise.

  • mars009

    The scary part in my opinion is all the “behind the covers” that is going on while using spring-boot. Spring-Roo caused me major headaches, when trying to use tomcat 5.5 and jsp, which is why we ended up dropping it (we were forced into tomcat 5, so not 100% Roo’s fault). Right now we are trying to jump on the Spring 4 wagon, so we’ll see how it goes. Thanks for the post btw!

    • http://steveperkins.net/ Steve Perkins

      Hey, thanks for reading! I had some similar experiences with Spring Roo a few years ago.

      Again, I don’t want to be too mean to those developers, but it just seemed to me that they were solving the wrong problem. Roo’s main strength was making it easier to create things like web controllers, JPA entities, etc. However, THAT part of Spring is already the easy part! Just create a POJO, and annotate it with “@Controller”, or “@Entity”, etc. The command-line tool was pretty neat to play with at first, but the truth is I don’t really need help with code generation. I just want some help getting a project spun up, and then get out of the way and let me do the coding party myself.

      Boot is more about filling that need. It’s “magic” is limited to your Maven POM, and your main application config class that you annotate with “@Configuration”. To remove Roo, you had to convert a bunch of AspectJ files into Java classes, and you were still left with a bit of a mess. To remove Spring Boot once you’re up and running, you’d just have to manually add all your dependencies to the POM, and manually add all your resources to the config class (i.e. JDBC data source, web view resolver, etc). In other words, the exact same steps you have to take to spin up a new Spring application from scratch in the first place anyway!

      As I indicated in the post, the “scary” part of Spring Boot right now is that it lacks full documentation for which resources it’s adding to your config class. I wouldn’t want to use it in production for a professional app until the documentation matures, so I have full and easy visibility into that. However, they seem to be heading in that direction, which is good. Fundamentally, I don’t think that Spring Roo’s “lock-in” factor applies to Spring Boot.

      • mars009

        Sorry for the late reply! Yeah documentation is nowhere to be found right now. I spent at least 2 hours today trying to update a project I am working on, but just getting the stuff together is difficult since I don’t really know what to change, where to change and what not to touch.

        Oh and getting rid of Roo…I remember rewriting the whole project since it was way easier than trying to get rid of all the AspectJ files.

  • AlexSerov

    Unjustified complexity is a common problem for java web frameworks. The answer to that challenge is some “minimalistic” frameworks, one of them is HybridJava.

  • Martin Flower

    Thanks Steve for a thorough background article. Having just watched Josh Long’s presentation, I’ve got a better understanding about which problem Spring Boot is attempting to solve. This is also the first time I’ve heard that jsps are on the way out. I thought it would all be single page apps & html, but now I’ve got to look at Thymeleaf : )

    • http://steveperkins.net/ Steve Perkins

      Wellllllllllll… I don’t know. I’ve been hearing that “JSP’s are on the way out” for well over a decade now!

      Sun/Oracle have been trying to push JEE developers toward JSF forever. SpringSource, which much more agnostic overall, nevertheless have always seemed to me as suggesting that templates are a better practice than JSP. Nevertheless, JSP has been the view layer for about 4 out of 5 Java web applications that I’ve ever seen. I’m not convinced that it will EVER go away!

      Thymeleaf is interesting. I’m not exactly sure that I like it “better” than Velocity or FreeMarker just yet, but it has been an interesting mental exercise to get up to speed with it. Basically, the way it hooks into your pages is more similar to the AngularJS client-side framework than anything I’ve ever seen on the server-side.

      • Martin Flower

        Yup, aware of JSF story, but I’ve been focussed on projects that use Spring. Can’t think of any of these that didn’t have jsps : )

  • MY1986

    Spring Boot rocks, I can’t wait until it matures. I tried Spring Roo a while ago and although it is easy to generate code i didn’t like how they tried to enforce the active record pattern, i prefer the repository pattern which Roo added support for later but there is little documentation on it. But the database reverse engineering that Roo does is amazing to quickly build prototypes. Also I tried to integrate Spring Roo with UI frameworks such as Vaadin and it was a nightmare, but the Vaadin guys (https://github.com/peholmst/vaadin4spring) are cooking up a storm using Spring Boot to integrate Vaadin seamlessly.

  • kgreenek

    I’m loving Spring Boot so far. Prior to this, I had only used php or python to develop server apps (I’m in the “recently graduated” hip 20-something startup-kid demographic). I had never used Spring before, but Spring Boot is so easy, I have used it now for a couple different personal projects.

  • Shaun Abram

    A very useful, balanced review of Spring Boot. Thanks Steve.

  • Hugh Jamieson

    Excellent post, Steve! This inspired me to dig a little deeper into boot after several attempts to stray from the HelloWorld examples ended in frustration. I totally agree with your notion that Spring offers a robust environment ONCE YOU SET IT UP! Figuring out where are the dials are hidden and how to turn on DEBUG logging is the key imho.
    Anyway, wanted to give props to the article!!!

  • Robert Winch

    Thanks for the very informative write up :) As the project lead of Spring Security, I’d love to have a constructive discussion on your statement “Then there’s Spring Security… but let’s not even talk about setting up Spring Security!” Can you expand on this a bit?

    • http://steveperkins.net/ Steve Perkins

      Thanks, Robert! Apologies for the delay in noticing this comment and question.

      Sorry for the tongue-in-cheek jab at your baby! :) I’m certainly not a guru-level Spring Security expert, so some portions of this feedback may be fair and other portions unfair. Various frustrations or issues I’ve had in the past have included the following:

      (1) Compared to other Spring add-ons, it seemsed like Security was a bit late the party in adopting Java-based configuration. I was once on a project that attempted to marry Java-configured Spring MVC with XML-configured Spring Security, and it was a very bad experience until we eventually gave up and reverted to XML-config throughout.

      (2) I once had to migrate a fairly large codebase from Spring 2.x to 3.x. Surprisingly, once I worked out all the Maven dependencies and classpath issues, there were virtually no code changes necessary… *except* in the Spring Security portions. I’m sorry for not recalling the exact details, but compared to rest of the Spring portfolio it was frustrating dealing with Security’s breaking changes.

      (3) I’m currently trying to incorporate Spring Security with a small Spring Boot application that I’m writing for learning purposes. I see that the Java-based configuration is solid now, and the documentation is much improved. Awesome! However, the main reason for including Spring Security was to facilitate OpenID support. The Spring Boot Security starter doesn’t include the OpenID pieces, so you have to figure out which exact version of that dependency to add to your Maven POM manually (and be careful to check it when you change the Spring Boot version).

      Also, this OpenID add-on is using a somewhat out-of-date third party library for most of its functionality… and it includes the Google Guice dependency-injection container alongside Spring’s (aiee!). I assume this is causing a multiple-classloader issue, because at runtime I’m getting ClassNotFoundExceptions for “org.w3c.dom.ElementTraversal”, which is in the Java 7 standard library. I’m about ready to give up and just implement OpenID support myself… it’s not a particularly difficult task.

      Numbers 4 and 5 really go hand-in-hand… Spring Security just feels too big and complex for most typical applications, and most developers don’t have to deal with it frequently enough to ever properly learn it:

      About ten years ago, I was still in the consulting field and worked for various IBM consulting partners. I was typically on-site at some Fortune 500 commerce or finance company, and typically interacting with Tivoli Access/Identity Manager or some similar monster. Back in those days, an easier way of navigating SAML tokens, CAS, JAAS, etc would have been very appreciated.

      Since that time, I’ve left IBM consulting and have mostly worked for large media companies and smaller commerce players. I haven’t had to deal with any of those aforementioned technologies AT ALL ever since. Once in a blue moon I still need to talk to an LDAP server, or deal with an ACL structure that’s more complex than “users” vs “admins”. However, it’s rare that I need more than 10% of what Spring Security brings to the table… and I would wager that I’m fairly typical. Even in Fortune 500 commerce and finance companies, I’m not sure how much of that the typcial developer needs today. Meanwhile, widely adopted contemporary standards such as OAuth seem missing altogther.

      For most web applications I’ve seen over the past decade, all they really needed for authentication was to implement an “interceptor” or “filter” (a basic construct in almost every web framework). Intercept all HTTP requests that are not going to your login page, and check for an indication of a currently authenticated session. Have your login page validate credentials (following OWASP recommended practices), and store the indication that will subsequently be checked by the interceptor.

      This is fairly basic, understandable, and only takes a couple dozen lines of code even in a verbose language like Java. Just as importantly, it’s the sort of thing you usually only touch once, very early in an application’s development. Once the authentication mechanism is in place, you generally don’t mess with it further or even think about it until you start your writing your next application (which might be years later).

      THAT’S the biggest pain point with Spring Security for me. It’s dramatically more feature-heavy and complex than I need on most projects, and it takes awhile to sort out configuration/classpath issues and get up the learning curve. Then it’s two or three years before I need to do that again. By then I’ve forgotten what I did last time around, and Spring Security has had undergone changes as well, so I’m always starting back at square one and re-learning the thing from scratch every time.

      Don’t get wrong, I think that the basic ideas in Spring Security are fantastic. I particularly love the way it facilitates using CSRF tokens, and wish that more developers were familiar with that and used them more dilligently. Overall, I just think it’s too complex. It includes too many outdated or niche technologies, while missing contemporary pieces like OAuth. It tends to lag behind the rest of the Spring portfolio, with dodgy integration (i.e. the Spring Security OpenID sample app works, and the Spring Boot sample projects work, but trying to make both those pieces work together is rough). It’s great once someone has gone through the trouble of setting it up in an application, but it’s not very fun being that person who plows the field up-front.

      Sorry for the length, and the… uh… candor. :) Thanks for asking, and thanks for your work on the project!

      • Robert Winch

        Sorry for the tongue-in-cheek jab at your baby!

        No apology necessary. It is great to get candid feedback to try to improve things; there is always room for improvements. In fact, in the future I would love to hear feedback via JIRA, twitter @rob_winch, etc.

        I’m going to do my best to respond your comments as concisely as possible. Please let me know if you feel like I overlooked something.

        = Behind the curve

        It seems like one of the complains you have is that Spring Security is behind the curve. One example you mention is that Spring Security was long missing Java Configuration. Another example you provided was that it is missing contemporary pieces like OAuth.

        I do agree Spring Security has been a bit behind on things. Since I started working full time and leading the project on Spring Security I have been doing my best to catch us up. As of Spring Security 3.2 (last year) we now have Java Configuration. In regards to OAuth, have you seen the Spring Security OAuth project?

        While these do address some of your specifically mentioned concerns, I do think we have some catching up to do. Here are some of the features that are coming up:

        * WebSocket support

        * Custom Session implementation – Assume a user has authenticated at the library and forgot to log out. They can log into their account and view active sessions and terminate it programatically. This also allows supplying the session identifier in a different manner. For example, in a REST API you don’t want to use JSESSIONID for the user information. Instead, you can have a header that contains the session information.

        * Spring Data integration – easily integrate Spring Security user information into your Spring Data queries. This is particularly meaningful when you have paged results

        * Testing support – easily run your tests as a particular user with full integration with Spring MVC Test Framework

        * Improved password storage mechanisms

        I really hope to have the following in Spring Security 4, but as things pile up it is seeming more likely it will come in the release after.

        * Multifactor authentication

        * Mutual authentication

        * Complete rewrite of the documentation

        Ultimately no framework will meet the needs of every individual. However, I hope that before you dismiss Spring Security as an option that you reach out. This can be as simple as filing a JIRA for a bug or feature request to providing a pull request with new functionality or sending me a link to a SO question via twitter @rob_winch. The more feedback we get from the community (both good & bad) the better the project can become.

        = Passivity

        there were virtually no code changes necessary… *except* in the Spring Security portions.

        As a former Spring Security user, I have experienced similar pain points with Spring Security in the past. As of Spring Security 3.1.1 I have been the project lead and I can assure you that passivity (in non-major releases) is extremely important. If you find a non-passive change it should be logged as a bug and I will be certain to fix it quickly.

        = OpenID

        It sounds as though you are having some problems with the OpenID integration.

        == Dependent libraries

        I will admit the openid4java library that we depend on has some nuances about it. For example, the guice dependency you mentioned is not ideal in a Spring environment. Typically Spring Security doesn’t try to implement these protocols but depend on a good library. The reason for this is that there are so many standards out there, it is very challenging to stay up with everything. Do you have any openid libraries you would recommend?

        == OpenID & Spring Boot

        I’m sorry to see you are having problems integrating Spring Boot and OpenID. I have replied to a few of your comments below.

        The Spring Boot Security starter doesn’t include the OpenID pieces

        This is true, but the starter shouldn’t pull in every dependency that Spring Security has. Having all the dependencies included would provide a lot of bloat for developers.

        so you have to figure out which exact version of that dependency to add to your Maven POM manually (and be careful to check it when you change the Spring Boot version).

        I’m not certain I understand the problem here. All you need to do is add spring-security-openid and omit the version (Spring Boot will take care of versions for you).

        I’m about ready to give up and just implement OpenID support myself… it’s not a particularly difficult task.

        I would really like to discourage you from implementing Security on your own. Even seasoned security experts should be careful implementing libraries themselves. Even if you decide to go with another framework, please do not implement security on your own.

        I’m getting ClassNotFoundExceptions for “org.w3c.dom.ElementTraversal”, which is in the Java 7 standard library

        I’m curious why this is happening. I was able to combine the openid-jc Spring Security sample with a Spring Boot application pretty easily. You can find the sample on github at https://github.com/rwinch/spring-boot-openid I was then able to authenticate using my Google account without any problems.

        Does this help you get things working? Can you provide your sample and/or instructions to reproduce the issue you are seeing?

        = Complexity

        You mentioned:

        This is fairly basic, understandable, and only takes a couple dozen lines of code even in a verbose language like Java.

        I understand that it appears much easier to implement things yourself. However, I can assure you that even simple password based authentication is not a trivial task to do. Unless security is something you do every day, which is unlikely since most developers have customer facing problems they are solving, you are likely overlooking something.

        In your couple dozen lines of code, do you consider:

        * Session Fixation Attacks

        * Timing attacks – If you use .equals in your code (to compare the passwords) you are likely exposed to timing attacks

        * CSRF protection

        * Clickjacking protection

        * Proper Security HTTP Response headers

        * … the list is actually much longer than you probably care to read but look at the Spring Security reference doc for more …

        Just as importantly, it’s the sort of thing you usually only touch once, very early in an application’s development. Once the authentication mechanism is in place, you generally don’t mess with it further or even think about it until you start your writing your next application (which might be years later).

        The other question I ask is if you are only thinking about security at the time you are putting it in place, then how do you know you are mitigating the latest attacks? With a framework, this is often gotten as soon as you update. What is more, the code has been tested and verified by the entire open source community.

        I do agree that upgrades should be seamless. If you do have any issues, please log a JIRA and it will be fixed in a very timely manner.

        If I change your mind on one thing, I hope it is to never implement security on your own. Please use an open source framework to secure your application (even if it is not Spring Security).

        • http://steveperkins.net/ Steve Perkins

          = OPENID & OAUTH

          That’s interesting that there’s a separate “Spring Security OAuth” project. I had no idea. Even after you told me about me about it, it took awhile to track down. It doesn’t appear on the “spring.io” website’s laundry list of projects, and even when you click through to “Spring Security” it’s kinda tucked away in the bottom corner.

          I know that the overall Spring website is going through a lot of re-vamping these days. Perhaps there are ways to make the Security sub-projects more visible. If not, then I would suggest promoting them more when you rewrite the base documentation.

          After researching the current state of OAuth and OpenID, it seems that they are presently in a very weird state of flux. The reason why I told you that Spring’s OpenID dependencies were out-of-date is because I was looking at the list of libraries recommended on the OpenID website, and there were newer ones more actively maintained. However, the newer one’s pertain to “OpenID Connect”, which is not really OpenID at all.

          What seems to be meant by “OpenID Connect” is that traditional OpenID is dying, and the path forward for all the major players (e.g. Google, Microsoft, Yahoo, etc) is use OAuth for everything. “OpenID Connect” simply means to use OAuth for authentication, without any of its authorization capabilities, and call it the new OpenID. That’s a bit of a bummer for me, because OAuth is a much more onerous animal to deal with. My understanding is that you could use traditional OpenID without having any relationship with the provider, whereas the OAuth providers I’ve looked at require you to register your application and setup crytographic tokens.

          Anyway, long story short… I’ve decided that it isn’t worth investing effort into traditional OpenID due to its impending demise, whereas “OpenID Connect” is not quite mature and polished enough for me to want to sink in a lot of time there either. I backed off on my plans for my application, and will only be supporting local authentication for now.

          = INTEGRATION WITH SPRING BOOT & OTHER CUSTOMIZATIONS

          Notwithstanding the fact that I dropped OpenID, I worked through all of my other issues in integrating Spring Security with my Spring Boot application (https://github.com/steve-perkins/fitnessjiffy-spring).

          Once you get it working, it looks so simple! However, it took a lot of experimentation to get working. Most of this is due to the fact that I did not want to use the default schema for users and authorities, but rather make Spring Security integrate with my existing database schema (this has been the requirement on almost every real-world Spring project I’ve ever seen).

          I was able to do this by using a DaoAuthenticationProvider, and implementing my own custom UserDetailsService. However, I figured this out more by way of JavaDocs and crawling through raw source code, rather than the documentation.

          One of the frustrations I have with Spring Security docs and sample applications is they tend to work with InMemoryUserDetailsManagerConfigurer… or if you’re lucky, then JdbcUserDetailsManagerConfigurer using “withDefaultSchema”. In the next rewrite of the docs, I would suggest beefing up a section on JDBC-driven authentication… with a particular emphasis on how to integrate with an existing schema rather than using the Spring Security one. Again, maybe I’m an unusual case, but I really have found that to be more of the real-world norm, especially in larger enterprise settings.

          = COMPLEXITY

          Shrug… maybe I’m just being cocky, but I honestly don’t think that traditional password authentication itself is all that complicated. Up until the past 5 years or so, you would use SHA-256 or something comparable, which is implemented for you in the “java.security” package. Use SecureRandom to generate a salt value… either one system-wide salt if you’re lazy, or a per-password salt to be thorough. Run the hash at least 1,000 times, and store both the hash and the salt. Later, when a raw password attempt is entered, repeat the process and see if the result matches the stored hash.

          Again, almost all of the difficult logic is implemented for you in the Java standard library, and the OWASP guidelines walk you through the higher-level process (https://www.owasp.org/index.php/OWASP_Java_Table_of_Contents).

          More recently, you would use BCrypt instead of SHA-256… which is even easier to manage, since the salt gets automatically stored as part of the hash itself. Again, the high-level process should be easy to follow, and nobody re-implements the truly low-level cryptographic process themselves anyway (even Spring Security cut-n-pasted its BCrypt implementation straight from the “jbcrypt” project).

          Beyond simple password authentication, the other list of features you hinted at are indeed very valid and important. However, I reject any implied notion that these things are all “magically” handled by the framework, such that the developer doesn’t need to know what they’re doing. As I said initially, Spring Security’s support for CSRF tokens is awesome. But Spring doesn’t automatically add that token tag to every single HTML form in your application. For that, you need a diligent developer… who knows to always include the tag manually. The developer is mostly likely to be diligent if he or she REALLY understands what they’re doing and why.

          Spring Security protects against clickjacking, through the “frame-options” and “xss-protection” options. But this isn’t automatically enabled by default. A developer has to understand the risk, and make a deliberate decision to enable those.

          Sure, there are some things that are across-the-board and automatic (e.g. session fixation). However, many if not most things require knowledge and genuine understanding from the developer to properly employ. You may shudder at the hypothetical developer saying, “I don’t need a security framework”. I shudder at the hypothetical developer saying, “We don’t have to worry about that stuff, I’m using a security framework”.

          There is an inherent tension between encouraging people to rely on a third-party framework, while expecting them to largely understand exactly what the framework is doing in order to use it properly. Frameworks used as time-savers and best practice guides are awesome. When used as “magical” substitutes for understanding the underlying domain yourself, they’re horrifying.

          • Robert Winch

            >> I would suggest beefing up a section on JDBC-driven authentication… with a particular emphasis on how to integrate with an existing schema rather than using the Spring Security one.

            You are completely right. There needs to be more documentation in general and we are working on that.

            >> As I said initially, Spring Security’s support for CSRF tokens is awesome. But Spring doesn’t automatically add that token tag to every single HTML form in your application.

            If you are using supported view technologies (i.e. Spring JSP tag lib or Thymeleaf), the Spring Security CSRF token is added automatically. If the token is not being added automatically, Spring Security has CSRF protection enabled by default. This means that when the token is not present developers will be forced to figure out why things are not working and learn about CSRF.

            >> Spring Security protects against clickjacking, through the “frame-options” and “xss-protection” options. But this isn’t automatically enabled by default.

            They are enabled by default when using Java Configuration. We did not enable by default with XML for passivity reasons, but it will be on by default in the next major release (4.x will be out in Q4).

            >> I shudder at the hypothetical developer saying, “We don’t have to worry about that stuff, I’m using a security framework”.

            This is true, but you don’t need to worry about as many things. Frameworks, when done properly, can alleviate many of the things for you. How do you compare the BCrypt hash for encoded passwords? Do you use expectedHash.equals(actualHash)? How many engineers would do this? If so, you are exposed to timing attacks. While OWASP is a good start, it does not outline everything you need to know about securing your application.

            >> When used as “magical” substitutes for understanding the underlying domain yourself, they’re horrifying.

            Agreed. The same can be said about leveraging any library. For example, using JPA wrong can mean you run into the ( n+1 problem).

            What can be said about libraries and frameworks is that it makes it easier to get things right. Security is very difficult to get right and it is unlikely any individual will get it right on their own. This is why I encourage you to use some framework / library for your security needs.

  • Greg Turnquist

    Steve,

    If you’ll grant me thirty seconds of self promotion, I have a book coming out next month called “Learning Spring Boot” ( http://blog.greglturnquist.com/category/learning-spring-boot ). It addresses several of the issues mentioned in the comments.

    * Many people have expressed concern about the “black magic” behind the scenes of Boot. Part of this book goes into detail about how to debug & manage your Boot app in development as well as production. It introduces you to MANY tools that come out of the box (including the auto-configuration report I contributed) to find out what Spring Boot auto-configured and why.
    * People are often interested in developing apps on their desktop with throwaway databases, but switching to persistent databases in production. This subject is covered as well.
    * Several comments went back and forth regarding Spring Security + Spring Boot. There’s a whole chapter that talks about this and some of your options to get up and going. When it comes to fine tuning things, such as using your own user/role schema, that subject is also addressed. LDAP/OpenID/OAuth/CAS/Kerberos/???, well, those aren’t covered so much, since they are relatively niche technologies. But perhaps http://spring.io/guides/gs/authenticating-ldap can assuage some of your concerns at least in the realm of LDAP.

    The isn’t everything in the book, but hopefully it can whet your appetite for something written in the vein of developers sitting down to write real world apps and their desire to get up and going FAST with options to override default opinions down the road.