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.

Be Sociable, Share!
Social tagging: > > >

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

  1. ozy says:

    I can’t tel how was this helpful. It connects all flying pieces in my mind.Thanks so much. Very clear explanation

  2. ozy says:

    will be nice if you put ”
    In the next article, we are going to look at all the Authentication interfaces”

    • admin says:

      I’m not sure what you mean?

      One thing that would be nice is if I found the time to be able to write the next article. I ended up getting really booked up. Almost for the next full year. But I promise in the next week I will put up the next article.

      Also, thanks for the real comments. Yours were the first ones. I had gotten at least 20 spam comments.

      Mark

  3. umesh says:

    It was really nice. But I would like to see the more descriptive, code snap shot and any flow diagram will be great an fast to graps. Although the explanation given above is good enough to clear the picture.
    Thanks
    umesh

    • admin says:

      In the description of the post, I specifically say that it is not an article about code, but about the concepts within Spring Security.

      So adding code snap shots and flow diagram would be a different post than the point of this post. Thanks for the comment.

      Mark

  4. Aparna says:

    Very clearly explained. If you could provide more details about interfaces and sample code, it would really be great.

    • admin says:

      Did you read my last reply to the last guy that asked for more code? THIS article is about the concepts, never ever should it have code. It is to explain the definition of the terms used. So NO, there will never ever be code in this article. SO anyone who asks in the future, I will just not approve their comment.

  5. Brajesh says:

    Wonderful article

Leave a Reply to Aparna Cancel reply