17 octobre 2018

Secure your application with Spring Security


Spring Security is a lightweight security framework that provides authentication and authorization support to secure Spring applications. It comes with implementations of popular security algorithms.
This article guides us through the process of creating a simple connection example to an application with Spring Boot, Spring Security, Spring Data JPA and MYSQL.


Let’s begin with a very basic application (in terms of installation requirements) that starts a Spring application context. Two tools that will help us with this are Maven and Spring Boot. I will be skipping lines that are not particularly interesting like the Maven repository configuration. You can find the complete code on GitHub.
To start off we will add the following dependency to the pom of our application.

1.  <dependency>
2.    <groupId>org.springframework.boot</groupId>
3.    <artifactId>spring-boot-starter-security</artifactId>
4.  </dependency>

At the start of our application we can see the following information in the console:

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 :: Spring Boot ::        (v2.0.4.RELEASE)
2018-09-10 22:44:09.059  INFO 645 --- [           main] .s.s.UserDetailsServiceAutoConfiguration : 
Using generated security password: c657aef6-758a-409d-ac02-814ff4df55be

Spring Boot therefore provides us with a default password.

We have just added Spring Security to our application’s classpath, Spring sets a default configuration, and asks a username and a password to access our application.
So to access our application with the Spring default configuration, we enter the username as username and the default password provided by Spring, displayed in the console at the start of our application (here c657aef6-758a-409d-ac02-814ff4df55be) in the authentication form.

Spring Boot 1

In the rest of this article, we will be customizing this configuration.


We are going to create the User.java class, this class implements UserDetails interface.
The interface provides information about the primary user. Implementations are not used directly by Spring Security in a matter of security purposes. They simply store user information that is then encapsulated in authentication objects. This makes it possible to store non-security related information (such as e-mail addresses, etc.) in an appropriate location.

@Table(name = "USER")
public class User implements Serializable , UserDetails {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer userId;
    private String username;
    private String password;
    public Integer getUserId() {
        return userId;
    public void setUserId(Integer userId) {
        this.userId = userId;
    public String getUsername() {
        return username;
    public boolean isAccountNonExpired() {
        return false;
    public boolean isAccountNonLocked() {
        return false;
    public boolean isCredentialsNonExpired() {
        return false;
    public boolean isEnabled() {
        return false;
    public void setUsername(String username) {
        this.username = username;
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    public String getPassword() {
        return password;
    public void setPassword(String password) {
        this.password = password;

Below are the feed scripts from our table in the H2 embedded database. The script is placed in the data.sql file, the scripts located in the data.sql file are executed each time we start our application.

INSERT INTO USER(username, password) VALUES('ADMIN', 'ADMIN')


Spring Security provides a variety of options in order to perform authentication. All of these options follow a simple contract. AuthenticationProvider processes an authentication request and a fully authenticated object with full credentials is returned.
The standard and most common implementation is the DaoAuthenticationProvider – which retrieves user details from a simple read-only DAO user – the UserDetailsService. This detail user service can only access the user name to retrieve the complete user entity and in most cases, this is sufficient.

public class AppAuthProvider extends DaoAuthenticationProvider {
    UserService userDetailsService;
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;
        String name = auth.getName();
        String password = auth.getCredentials()
        UserDetails user = userDetailsService.loadUserByUsername(name);
        if (user == null) {
            throw new BadCredentialsException("Username/Password does not match for " + auth.getPrincipal());
        return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
    public boolean supports(Class<?> authentication) {
        return true;


We are going to create a UserRepository.java class, this class inherits the JpaRepository class. The function findUserWithName (String name) retrieves a User by his username.

public interface UserRepository extends JpaRepository<User, Integer> {
    @Query(" select u from User u " +
            " where u.username = ?1")
    Optional<User> findUserWithName(String username);


We are going to create the UserService.java class, this class implements a UserDetailsService interface. The UserDetailsService interface is used to retrieve the data related to the user. It uses a method called loadUserByUsername that finds a user based on the user name and can be overridden to customize the user’s search process. It is used by DaoAuthenticationProvider and loads details about the user during authentication.

public class UserService implements UserDetailsService {
    private final UserRepository userRepository;
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findUserWithName(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
        return user;


To customize the configuration we will create a class that inherits from WebSecurityConfigurerAdaptater. This class must have @EnableWebSecurity and @Configuration notes. Configuration classes are scanned when the application starts.

public class SecurityConfig extends WebSecurityConfigurerAdapter {
    UserService userDetailsService;
    private AccessDeniedHandler accessDeniedHandler;
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    protected void configure(HttpSecurity http) throws Exception {
                .authenticationEntryPoint(new Http403ForbiddenEntryPoint() {
                .successHandler(new AuthentificationLoginSuccessHandler())
                .failureHandler(new SimpleUrlAuthenticationFailureHandler())
                .logoutSuccessHandler(new AuthentificationLogoutSuccessHandler())
    private class AuthentificationLoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
        public void onAuthenticationSuccess(HttpServletRequest request,
                                            HttpServletResponse response, Authentication authentication)
                throws IOException, ServletException {
    private class AuthentificationLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
        public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
                                    Authentication authentication) throws IOException, ServletException {
    public AuthenticationProvider getProvider() {
        AppAuthProvider provider = new AppAuthProvider();
        return provider;

We define how users are managed in the configure(AuthenticationManagerBuilder auth) method. Here the user management is dynamic, we manage users via the service UserSevice.
Protected resources’ management is done on the level of the configure(HttpSecurityhttp) function. Any access to url / user / ** needs to be authenticated. The authentication is done via a request of type Post to url / login.


We are going to test the access to our application using Postman Rest, which is a API web client.
By accessing GET: / user / we have an authentication error as below:

spring boot 2

Access to GET: / user / needs to be authenticated beforehand.
To authenticate it we will access POST: / login with a User present in our database.

Spring Boot 3

We have a 200 Status, so authentication has worked.
So we will again access GET: / user /

Spring Boot 4


This article showed us how to use Spring Security to secure its Spring Boot application. You can find the complete code on GitHub.

Écrit par


Submit a Comment

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *