Spring security is designed to provide both authentication and authorization to Java applications.
This article mainly try to describe spring security from a general concept view, give you a whole picture of how the spring security works in most usage. Other articles are:
Understand spring security easily – developer view (to be continued)
Understand spring security easily – annotation example (to be continued)
0. Basic senario
In this serial we only focus on the most popular senario, web application security and using username+password to get access. Passwords are stored in database. This article is based on spring security 4.x
1. key concept
Credential – namely password in our username + password senario.
Princple – you can think it’s a kind of identification of a user. It includes username, password and all the authorities that this user has. Most authentication mechanisms withing spring security return an instance of UserDetails as the principal.
UserDetails – just an interface in package org.springframework.security.core.userdetails. Like said above, an instance of UserDetails always used as identification of a user. What does this mean? It means when you read you database get all information for a user, you finally get a instance of UserDetails.
3 most used methods of UserDetails are getUserName(),getPassword and getAuthorities().
Spring security provide a implementation, org.springframework.security.core.userdetails.User. But in practicle, in a spring project with ORM, you normally will have your own implementation of UserDetails. It’s often looks like:
public class CustomUser extends YourUserEntity implements UserDetails { //... }
Spring security will use UserDetails instance created according to database to test browser provided info. Now the question is, “create UserDetails instance”, where does this happen? In UserDetailsService.
UserDetailsService – This interface only has one method,UserDetails loadUserByUsername(String username)
In real project you also need to provide an implementation of this interface and it often looks like:
public class CustomUserDetailsService implements UserDetailsService { @Override UserDetails loadUserByUsername(String username) { // access database by DAO or Spring data repository CustomUser userInDatabase = (CustomUser)yourUserEntityRepository.findByUsername(username); return userInDatabase; } }
This is the place you put your own code to access database to load user information.(We define CustomUser as a child of YourUserEntity, remember?)
1. Filter Chain
The spring security is mainly build on servlet filters. Filter has a doFilter(…,FilterChain chain) . In method doFilter , there’s always a call to chain.doFilter(), which devides the filter into 2 pieces. Code before chain.doFilter() run before the request reach any servlet, code after chain.doFilter() run after the request being processed and before response send back to browser.
There are many filters in spring security and the order of these filters matters. Here is a filter list from spring security reference. There are 10+ filters in spring security, but check several key filters:
- UsernamePasswordAuthenticationFilter – This filter get your http post username + password and create and verify the password.
- ExceptionTranslationFilter – If not authenticated, jump to login page.
- FilterSecurityInterceptor – if the logined user has right to access the target url. (Authorization)
- These 3 filters are key to understand the work flow of spring security authentication and authorization.