Understanding the big picture

Exclusive offer: get 50% off this eBook here
Instant Spring Security Starter [Instant]

Instant Spring Security Starter [Instant] — Save 50%

Learn the fundamentals of web authentication and authorization using Spring Security with this book and ebook

$14.99    $7.50
by Jakub Nabrdalik Piotr Jagielski | September 2013 | Open Source

In this article, by Piotr Jagielski and Jakub Nabrdalik, the authors of Instant Spring Security Starter, covers in detail the security provided by Spring.

(For more resources related to this topic, see here.)

So we've got this thing for authentication and authorization. Let's see who is responsible and what for.

There is an AccessDecisionManager, which, as the name suggests, is responsible for deciding whether we can access something or not; if not, an AccessDeniedException or InsufficientAuthenticationException is thrown.

AuthenticationManager is another crucial interface. It is responsible for confirming who we are.

Both are just interfaces, so we can swap our own implementations if we like.

In a web application, the job of talking with these two components and the user is handled by a web filter called DelegatingFilterProxy, which is decomposed into several small filters. Each one is responsible for a different thing, so we can turn them on, off, or put our own filters in between and mess with them anyway we like. These are quite important, and we will dig into them later. For the big picture, all we need to know is that these filters take care of all the talking, redirect the user to the login page (or an access-denied page), and save the current user details in an HTTPSession.

Well, the last part, while true, is a bit misleading. User details are kept in a SecurityContext object, which we can get a hold of by calling SecurityContextHolder.getContext(), and which in the end is stored in HTTPSession by our filters. But we had promised a big picture, not the gory details, so here it is:

Quite simple, right?

If we have an authentication protocol without login and password, it works in a similar way. We just switch one of the filters, or the authentication manager, to a different implementation. If we don't have a web application, we just need to do the talking ourselves.

But this is all for web resources (URLs). What is much more interesting and useful is securing calls to methods. It looks, for example, like this:

@PreAuthorize(["isAuthenticated() and hasRole('ROLE_ADMIN')"])
public void somethingOnlyAdminCanDo() {
}

Here, we decided that somethingOnlyAdminCanDo will be protected by our AccessDecisionManager and that the user must be authenticated (not anonymous) and has to have an admin role. Can a user be anonymous and have an admin role at the same time? In theory, yes, but it would not make any sense. Because it's much cheaper to check if he is authenticated and stop right there. We see a bit of optimization in here. We could drop the isAuthenticated() method and the behavior wouldn't change.

We can put this kind of annotation on any Java method, but our configuration and mechanism to fire up the security will depend on the type of objects we are trying to protect.

For objects declared as Spring beans (which is a short name for anything defined in our Inversion of Control (IoC) configuration, either via XML or annotations), we don't need to do much. Spring will just create proxies (dynamic classes) that take over calls to our secured methods and fire up AccessDecisionManager before passing the call to the object we really wanted to call. For objects outside of the IoC container (anything created with new or just code not defined in Spring context), we can use the power of Aspect Oriented Programming (AOP) to get the same effect. If you don't know what AOP is, don't worry. It's just a bit of magic at the classloader and bytecode level. For now, the only important thing is that it works basically in the same way. This is depicted as follows:

We can do much more than this, as we'll see next, but these are the basics.

So, how does the AccessDecisionManager decide whether we can access something or not?

Imagine a council of very old Jedi masters sitting around a fire. They decide whether or not you are permitted to call a secured method or access a web resource. Each of these masters makes a decision or abstains. Each of them can consult additional information (not only who you are and what you want to do, but every aspect of the situation). In Spring Security, those smart people are called AccessDecisionVoters, and each of them has one vote.

The council can be organized in many different ways. It has one voice, and so it may make the decision based on a majority of votes. It may be veto-based, where everything is allowed unless someone disagrees. Or it may need everyone to agree to grant access, otherwise access is denied. The council is the AccessDecisionManager, and we have three implementations previously mentioned out of the box. We can also decide who's in the council and who is not. This is probably the most important decision we can make, because this will decide the security model that we will use in our application.

Let's talk about the most popular counselors (implementations of AccessDecisionVoter).

  • Model based on roles (RoleVoter): This guy makes his decision based on the role of the user and the required role for the resource/method. So if we write @PreAuthorize("hasRole('ROLE_ADMIN')"), you better be a damn admin or you'll get a no-no from this guy.
  • Model based on entity access control permissions (AclEntryVoter): This guy doesn't worry about roles. He is much more than that. Acl stands for Access Control List, which represents a list of permissions. Every user has a list of permissions, possibly for every domain object (usually an object in the database), that you want to secure.

    So, for example, if we have a bank application, the supervisor can give Frank access to a single specific customer (say, ACME—A Company that Makes Everything), which is represented as an entity in the database and as an object in our system. No other employee will be able to do anything to that customer unless the supervisor grants that person the same permission as Frank.

    This is probably the most scrutinous voter we would ever use. Our customer can have a very detailed configuration with him/her. On the other hand, this is also the most cumbersome, as we need to create a usable graphical interface to set permissions for every user and every domain object. While we have done this a few times, most of our customers wanted a simpler approach, and even those who started with a graphical user interface to configure everything asked for a simplified version based on business rules, at the end of the project.

    If your customer describes his security needs in terms of rules such as "Frank can edit every customer he has created but he cannot do anything other than view other customers", it means it's time for PreInvocationAuthorizationAdviceVoter.

  • Business rules model (PreInvocationAuthorizationAdviceVoter): This is usually used when you want to implement static business rules in the application. This goes like "if I've written a blog post, I can change it later, but others can only comment" and "if a friend asked me to help him write the blog post, I can do that, because I'm his friend". Most of these things are also possible to implement with ACLs, but would be very cumbersome.

    This is our favorite voter. With it, it's very easy to write, test, and change the security restrictions, because instead of writing every possible relation in the database (as with ACL voter) or having only dumb roles, we write our security logic in plain old Java classes. Great stuff and most useful, once you see how it works.

    Did we mention that this is a council? Yes we did. The result of this is that we can mix any voters we want and choose any council organization we like. We can have all three voters previously mentioned and allow access if any of them says "yes". There are even more voters. And we can write new ones ourselves. Do you feel the power of the Jedi council already?

    Do you feel the power of the Jedi council already?

Summary

This section provides an overview of authentication and authorization, which are the principles of Spring security.

Resources for Article :


Further resources on this subject:


Instant Spring Security Starter [Instant] Learn the fundamentals of web authentication and authorization using Spring Security with this book and ebook
Published: June 2013
eBook Price: $14.99
See more
Select your format and quantity:

About the Author :


Jakub Nabrdalik

Jakub Nabrdalik was born a year before Commodore 64 was introduced, and soon started programming text-based adventure computer games for that machine. He got his B.Sc. from the University of Warmia and Mazury, and his M.Sc. from Military University of Technology, both in Poland. Sucked up by the world's transition to the Web, he started building ERP, e-commerce, and enterprise systems on a thin client with PHP, C#, Java, and Groovy. In 2005, his life was changed dramatically by Test Driven Development. As a strong believer in the Agile Manifesto and Craftsmanship, he started sharing his passion by speaking at conferences (33rd Degree, TopConf, Confitura, and Javarsowia), Warsaw Java User Group meetings, Agile Warsaw meetings, and mentoring/coding at several workshops and Hackathons.

Since 2007, he has been working as a Solution Architect at TouK, a medium-sized Agile company, making dedicated software for telcos, banks, and smaller customers. His main goal is to build highly maintainable services, in a very time-and-money-constrained environment. He blogs a bit at blog.solidcraft.eu.

Piotr Jagielski

Piotr Jagielski graduated in Computer Science from Warsaw University, where he encountered functional (SML) and logic (Prolog) programming 10 years before Seven Languages by Bruce A. Tate was published. He started coding for money with C++, and after two years, switched to Java, which he still uses to this day (with a little help from Groovy) in both integration middleware and frontends as a senior developer at TouK.

In his spare time, he discovers tech startups and trending open source frameworks, which has led him to create a framework rating system at DevRates.com. He spent the last couple of months hacking Raspberry Pi and Arduino, with some quite successful proofs-of-concept (he won second place in Hackwaw for a teddy bear baby monitor).

He is also a husband and the geek dad of a 2-year-old geek boy.

Books From Packt


Spring Security 3.1
Spring Security 3.1

Spring Security 3
Spring Security 3

Spring Roo 1.1 Cookbook
Spring Roo 1.1 Cookbook

 Spring Data
Spring Data

Spring Persistence with Hibernate
Spring Persistence with Hibernate

Spring Web Services 2 Cookbook
Spring Web Services 2 Cookbook

Instant Spring for Android Starter [Instant]
Instant Spring for Android Starter [Instant]

Instant Spring Tool Suite [Instant]
Instant Spring Tool Suite [Instant]


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software