Spring Security Overview

Spring 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();
}

Represents an authority granted to an Authentication object.