Archives for May2012

Introduction to Spring Security – The Architecture and Design – Part 1

In this multi part article I am going to explain the key components/classes/interfaces that make up Spring Security architecture and design. By understanding these components, we will be able to show in future articles how to customize Spring Security with simply implementing an interface and configuring it as a Spring bean.

The main thing to understand about Spring Security is that it is broken down to many little parts or interfaces for each piece of the security solution. Each part is responsible for just a small portion of the big security picture. So instead of having just a couple of classes to handle everything, which would be less flexible, less customizable, low cohesion and tightly coupled, we have an architecture that is based on many interfaces, such that we can swap out implementations with either built in components or our own custom implementations, at will, without affecting other parts of your security solution and your application.

But this means that you need to know all of these interfaces/classes and what role/responsibility each one has. You also must know how much of a security solution you need. Do you want coarse or fine grained authorization, from group-based to role-based or down to fine grained access control lists based on application data? Do you just need authentication but not authorization?

You might also ask, where do you store your user information for authentication and authorization? is it in a database, LDAP, Active Directory? Do you need encryption? What type of encryption? What are you securing? Is it just a URL for a web page, or is it parts of a web page? Is it JMS Messaging or SOAP Web Services that need to be secured? How about all your code should your methods being secured too? These are many of the factors that will determine what parts of Spring Security you need to use.

Great now that I have completely confused you, let me confuse you some more! This is why I need at least a two part article to cover many of these components. This first part will be on Authentication and the second part will be on Authorization.

First we will talk about a user. This is a username and password as well as some type of authorization information. In Spring Security we have an interface called a UserDetails to store that information. A UserDetails implementation will store a String for the username as well as a String for the password, and it will have a collection of objects called GrantedAuthority. A GrantedAuthority object is just a holder class to hold a String for each role that the UserDetails/user has. So if I have a user Bob who has ROLE_ADMIN and ROLE_USER assigned to them in a database, then Bob’s UserDetails instance will have two GrantedAuthority instances in its collection. There are a couple of other boolean properties that also need to be set with the UserDetails interface, one of these for instance is used to say whether the user is still active or enabled.

Now that we have an object to hold all the user information, UserDetails. How do we one created? How do we have someone log in and have Spring look up the user information, check that the enter their correct credentials and then have a UserDetails object instantiated and holding that user’s information? That is the role of authentication. And in Spring the main class responsible for controlling authorization is an interface called AuthenticationManager. It is a manager, so like all manager’s we know, it just delegates to others to do the actual work.

So what do we have to do here? There are really just two parts. 1) look up the user information and populate the UserDetails object with that information and 2) Check that the password matches. (there are other authenication mechanisms like certificates which are exactly user/password checking, but for simplicity right now we will ignore those scenarios)

If anything fails in these two steps, Spring Security will throw exceptions. If it is successful, then Spring Security will take the UserDetails object and store it somewhere so that we don’t have keep looking up that information again and again while the user is logged in.

Who does the AuthenticationManager delegate to? It will delegate to a collection of AuthenticationProvider instances. An AuthenticationProvider is an interface that maps to a data store which stores your user data. Based on the type of data store a query of some type must be used to get the data for the user.

For that part, an AuthenticationProvider will call an object that implements the UserDetailsService interface. A UserDetailsService looks up the user data and returns a UserDetails object fully populated. If the UserDetailsService cannot find this user then a UsernameNotFoundException is thrown. Why username not found? Because the UserDetailsService interface has just one method loadUserByUsername(String username). So when we go to our data store and query it, the only information we have is the String username to run our queries with.

Once the UserDetailsService returns a UserDetails object, then the AuthenticationProvider will check that the password matches the password the user entered. If it does not match, then the AuthenticationProvider will throw an AuthenticationException, or a subclass of it like BadCredentialsException. Thrown because the password or credentials that the user entered in the login screen were incorrect.

So the process goes something like this. A user enters their username and password into a login screen and clicks a login button. The entered information is placed into an object called Authentiation which is passed to the AuthenticationManager’s authenticate method. this method will loop through all AuthenticationProviders that are configured and calls their authenticate method, passing in the Authentication object. Each AuthenticationProvider will calls its configured UserDetailsService’s loadUserByUserName method.

In most applications, the configuration to set all this up is pretty easy. As a matter of fact, you can pretty much get all of it with just one tag from the security xml namespace. However, what will always be different with all your applications. That will be where and how you store your user data. Spring will not be able to predict that, so the configuration that you must do is to tell Spring Security what UserDetailsService do you want to use and assign it to an AuthenticationProvider.

In the next article (soon I promise), we are going to look at all the Authentication interfaces and configuration in detail.

Perfect World Programming Articles

In all of these articles, I will take a standard approach. There will be written articles, sample code, links to JavaDocs, as well as videos. The whole article consists of all these materials. I will rarely just write text or just a video, because I think we need to see things explained to us through many different types of media to fully understand.

This means that if you just read the article, or just watch the video you will miss out on a lot of material. Sometimes, it won’t make sense without looking at everything. I might not even talk about a real important subject in the article, but it is in the video, or just in the sample code. So please, take the time and look at everything and I think you will learn a lot from it.

Thank you for stopping by, and I hope your find it useful.


p.s. I moderate all the comments, so if you are going to post spam, you are just wasting time, yours and mine. They will never appear on the site, and I will never reply to any.