Spring Security Overview
So 23 April 2017Spring Security
This post is focusing on Spring security, especialy in case of Spring Boots Autoconfiguration.
Please check also Spring Security Guide which explains nearly everything on its own.
Here I want to write down a small overview to keep everything in mind what I read.
Getting started
Setup a Spring Boot project with Spring Initializr. Add Web and Security to generate your project.
Should look like this:
.
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── DemoApplication.java
│ └── resources
│ ├── application.properties
│ ├── static
│ └── templates
└── test
└── java
└── com
└── example
└── DemoApplicationTests.java
Now you can start testing all different configurations. See next, what is already configured.
I have done nothing - Default Configuration
If you just add Spring Security to your boot application, the autoconfiguration will protect your application with basic authentication.
This is achieved through an AuthenticationManager which uses an in InMemoryUserDetailsManager providing a default user called user with a random password. To get more context about the different components read Central Components
For more information check out Spring Boot Documentation
Central Components
WebSecurityConfigurerAdapter
WebSecurityConfigurerAdapter is used to configure the Spring Security Setup.
@Configuration
public static class ExampleConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
}
}
- configure(WebSecurity web):
Gets an shared WebSecurity object which is used to build the FilterChainProxy. - configure(AuthenticationManagerBuilder auth):
Configures an AuthenticationManagerBuilder which will be used to build a local AuthenticationManager. - configure(HttpSecurity http):
Configure web based security at resource level. This includes on which URL the security matches and which roles are allowed to access a resource.
FilterChainProxy
The FilterChainProxy is a delegating filter. It delegates to the most precision match of HttpSecurity matcher. For more information check out the mentioned Spring Security Guide
AuthenticationProcessingFilter
AuthenticationProcessingFilter is responsible to extract principal (username) and credential (password) from request and create an unauthoriced authentication (also called as authentication token).
The unauthenticated/ checking principal and credential will be done by the AuthenticationManager.
Authentication
Stores information: * authenticated (true/false) * authorities (List of GrantedAuthority) * principal/credentials (username/password)
Spring provides some general implementations like UsernamePasswordAuthenticationToken.
Authentication Manager
package org.springframework.security.authentication;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
public interface AuthenticationManager {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
}
AuthenticationManager gets unauthenticated authentications and checks principal and credentials. Without any configuration Spring will use a ProviderManager, which is an implementation of an AuthenticationManager, but delegates incoming authenticate() calls to AuthenticationProviders.
Global vs local
There exists a global parent AuthenticationManager that all local configured ones are connected to. Local configuration is handled through WebSecurityConfigurerAdapter that are most of the time responsible for just a subcontext of the url context path.
The ProviderManager will call its parent to authenticate, if no AuthenticationProvider authenticates the request.
Authentication Provider
package org.springframework.security.authentication;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
boolean supports(Class<?> authentication);
}
AuthenticationProviders are checking if the given unauthoriced Authentication is valid and returns an authoriced Authentication. If the Developer defines one AuthenticationProvider, it will be picked up and injected into the ProviderManager automatically. The Developer can also provide multiple AuthenticationProvider but those will not be picked up automaticcally, thay has to get configured through a config class that is annotated with @EnableWebSecurity
, @EnableGlobalMethodSecurity
, or `@EnableGlobalAuthentication. (For the global configuration.)
Referring to the Spring Docs
If you don't want to use global configuration, you are able to configure that in your WebSecurityConfigurerAdapter.
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(new TestingAuthenticationProvider())
.authenticationProvider(new TestingAuthenticationProvider());
}
}
UserDetailsService
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
The UserDetailsService is used to provide the simplest customication. If just a UserDetailsService is provided by the developer spring will use it in a DaoAuthenticationProvider, which is loading the "UserDetails" by username from the UserDetailsService and compares the credentials with these from authentication.
There are also some UserDetailsServices which are provided by Spring for common szenarios like for JDBC
GrantedAuthority
package org.springframework.security.core;
import java.io.Serializable;
import org.springframework.security.access.AccessDecisionManager;
public interface GrantedAuthority extends Serializable {
String getAuthority();
}
Links
- Spring Security Architecture Guide
- Spring Boot and Spring Security
- WebSecurityConfigurerAdapter Methods Explained
Represents an authority granted to an Authentication
object.