DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Enterprise AI Trend Report: Gain insights on ethical AI, MLOps, generative AI, large language models, and much more.

2024 Cloud survey: Share your insights on microservices, containers, K8s, CI/CD, and DevOps (+ enter a $750 raffle!) for our Trend Reports.

PostgreSQL: Learn about the open-source RDBMS' advanced capabilities, core components, common commands and functions, and general DBA tasks.

AI Automation Essentials. Check out the latest Refcard on all things AI automation, including model training, data security, and more.

Related

  • Authentication and Authorization: Mastering Security
  • Authentication With Remote LDAP Server in Spring WebFlux
  • Authentication With Remote LDAP Server in Spring Web MVC
  • How to Implement Two-Factor Authentication in A Spring Boot OAuth Server? Part 2: Under the Hood

Trending

  • Understanding Kernel Monitoring in Windows and Linux
  • Automated Data Extraction Using ChatGPT AI: Benefits, Examples
  • Machine Learning: A Revolutionizing Force in Cybersecurity
  • Building a Sustainable Data Ecosystem
  1. DZone
  2. Software Design and Architecture
  3. Security
  4. Spring Security Authentication

Spring Security Authentication

Security is one of the most vital concerns for any organization. In this article, you will learn about authentication and how to integrate them with Spring MVC.

By 
Mohamed Labouardy user avatar
Mohamed Labouardy
·
Manoj Debnath user avatar
Manoj Debnath
·
Updated Jan. 26, 24 · Tutorial
Like (28)
Save
Tweet
Share
179.0K Views

Join the DZone community and get the full member experience.

Join For Free

Authentication

Access to a secure domain must go through the process of authentication. Authentication verifies the identity of a person who requests access to a particular resource, based on which authorization is granted. For example, a common way to authenticate a user is through a username and password.

Spring Security

Spring is one of the most popular open-source frameworks of Java that evolved into a huge ecosystem that addresses multiple facets of enterprise application development. Spring Security is one of them which focuses on authentication and access-control mechanisms. It has built-in support for authenticating users. It is the de facto standard for securing Spring-based applications. 

Spring Security provides support for both authentication and authorization. While authentication verifies the identity of the user, authorization lays down the rules of access to the resource. Although the default authentication and authorization support is fine in most cases, the real power of Spring Security lies in its customization. It can be extended according to client requirements. The authentication support applies to both servlet and WebFlux environments.

Spring Security can be configured to protect against an attack like Session Fixation, Clickjacking, Cross-Site Request Forgery(CSRF), Brute Forcing, Man in the Middle(MITM), Cross-Site Scripting (XSS), etc. It can be well integrated with Servlet API as well as Spring Web MVC.

Why Spring Security?

The ecosystem of Spring provides a comprehensive programming and configuration model for developing small to a large enterprise application. Security is an indispensable part of any business application. 

  • It must be secure, and what better framework can one choose when Spring itself provides the necessary APIs? Related: Secure Spring REST with Spring Security and Oauth.
  • By using Spring Security, we are actually delegating the responsibility of determining the architecture and core security features to a team of experts. 
  • Spring Security has evolved since its inception and is in continuous development and has stood the test of time. 
  • So, when building a Spring application it is a good idea to include the Spring Security framework. They not only integrate well but are also reliable.

This article will delve into the technical capabilities of Spring Security, specifically authentication. To find the complete code for this article, check out this GitHub repository.

Read DZone’s guide on implementing OAuth 2.0 with Spring Boot.

The following diagram shows the fundamental process Spring Security uses to address this core security requirement. The figure is generic and can be used to explain all the various authentication methods that the framework supports:

Spring Security framework

Spring Security has a series of servlet filters (a filter chain). When a request reaches the server, it is intercepted by this series of filters (Step 1 in the preceding diagram). In the reactive world, with the new Spring WebFlux web application framework, filters are written quite differently from traditional filters, such as those used in the Spring MVC web application framework. Having said that, the fundamental mechanism remains the same for both.

The servlet filter code execution in the filter chain keeps skipping until the right filter is reached. Once it reaches the right authentication filter based on the authentication mechanism used, it extracts the supplied credentials — most commonly a username and password — from the caller.

Using the supplied values (here, you have a username and password), the filter UsernamePasswordAuthenticationFilter creates an Authentication object. In the preceding diagram, the UsernamePasswordAuthenticationToken is created with the username and password supplied in Step 2. The Authentication object created in Step 2 is then used to call the authenticate method in the AuthenticationManager interface:

public interface AuthenticationManager {
    Authentication authenticate(Authentication authentication) throwsAuthenticationException;
}


The actual implementation is provided by the ProviderManager, which has a list of the configured AuthenticationProvider.

public interface AuthenticationProvider {
    Authentication authenticate(Authentication authentication) throwsAuthenticationException;
    boolean supports(Class<?> authentication);
}


The request passes through various providers and, in due course, tries to authenticate the request. There are a number of AuthenticationProvider interfaces as part of Spring Security.

In the diagram above, AuthenticationProvider requires user details (some providers require this, but some don’t), which are provided in UserDetailsService:

public interface UserDetailsService {
    UserDetailsloadUserByUsername(String username) throws UsernameNotFoundException;
}


UserDetailsService retrieves UserDetails and implements the user interface using the supplied username.

If all goes well, Spring Security creates a fully populated authentication object (authenticate: true, granted authority list, and username), which will contain various necessary details. The authentication object is stored in the SecurityContext object by the filter for future use.

  • An authentication object with authenticated=true if Spring Security can validate the supplied user credentials
  • An AuthenticationException if Spring Security finds that the supplied user credentials are invalid
  •  null if Spring Security cannot decide whether it is true or false (confused state)

Setting Up the Authentication Manager

There are a number of built-inAuthenticationManagermethods in Spring Security that can be easily used in your application. Spring Security also has a number of helper classes, which you can set up using AuthenticationManager. One helper class is theAuthenticationManagerBuilder.

Using this class, it's quite easy to set up the UserDetailsService against a database, in memory, in LDAP, and so on. If the need arises, you could also have your own custom  UserDetailsService (maybe a custom single sign-on solution is already there in your organization).

You can make anAuthenticationManager global, so it will be accessible by your entire application. It will be available for method security and other WebSecurityConfigurerAdapter instances.

WebSecurityConfigurerAdapter is a class that is extended by your Spring configuration file, making it quite easy to bring Spring Security into your Spring application. This is how you set up a global  AuthenticationManager using the @Autowired annotation:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    public void confGlobalAuthManager(AuthenticationManagerBuilderauth) throws Exception {
        auth
            .inMemoryAuthentication()
             .withUser("admin").password("admin@password").roles("ROLE_ADMIN");
    }
}


You can also create local the  AuthenticationManager, which is only available for this particular WebSecurityConfigurerAdapter by overriding the configure method, as shown in the following code:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilderauth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser("admin").password("admin@password").roles("ROLE_ADMIN");
}


Another option is to expose the  AuthenticationManager bean by overriding the  authenticationManagerBean method:

@Override
public AuthenticationManagerauthenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}


You can also expose various  AuthenticationManager, AuthenticationProvider, or the UserDetailsService as beans, which will override the default ones.

The preceding code example has used AuthenticationManagerBuilder to configure in-memory authentication.

AuthenticationProvider

AuthenticationProvider provides a mechanism for getting the user details with which authentication can be performed. Spring Security provides a number of AuthenticationProvider implementations, as shown in the following diagram:

Authentication manager provider implementations

Custom AuthenticationProvider

You can also write custom supports like the  AuthenticationProvider by implementing the AuthenticationProvider interface. You have to implement two methods, namely, authenticate (authentication) and  Class<  ?  >aClass:

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
      String username = authentication.getName();
      String password = authentication.getCredentials().toString();

      if ("user".equals(username) && "password".equals(password)) {
            return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList());
       } else {
            throw new BadCredentialsException("Authentication failed");
       }
    }

    @Override
    public boolean supports(Class<?>aClass) {
        return aClass.equals(UsernamePasswordAuthenticationToken.class);
    }
}


On the GitHub page, navigate to the jetty-in-memory-basic-custom-authentication project to see the full source code of this class.

Multiple AuthenticationProvider

Spring Security allows you to declare multiple AuthenticationProvider implementations in your application. They are executed according to the order in which they are declared in the configuration.

The jetty-in-memory-basic-custom-authentication project is modified further, and you have used the newly created CustomAuthenticationProvider as an AuthenticationProvider (Order 1) and the existing as your second  AuthenticationProvider (Order 2) —  MemoryAuthentication:

@EnableWebSecurity
@ComponentScan(basePackageClasses = CustomAuthenticationProvider.class)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    CustomAuthenticationProvidercustomAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic()
            .and()
            .authorizeRequests()
            .antMatchers("/**")
            .authenticated(); // Use Basic authentication
    }

    @Override
    protected void configure(AuthenticationManagerBuilderauth) throws Exception {
        // Custom authentication provider - Order 1
        auth.authenticationProvider(customAuthenticationProvider);
        // Built-in authentication provider - Order 2
        auth.inMemoryAuthentication()
            .withUser("admin")
            .password("{noop}admin@password")
            //{noop} makes sure that the password encoder doesn't do anything
            .roles("ADMIN") // Role of the user
            .and()
            .withUser("user")
            .password("{noop}user@password")
            .credentialsExpired(true)
            .accountExpired(true)
            .accountLocked(true)
            .roles("USER");
    }
}


Whenever the authenticate method executes without error, the controls return, and, thereafter, the configured AuthenticationProvider doesn’t get executed.

Spring Security Spring Framework authentication Web application

Opinions expressed by DZone contributors are their own.

Related

  • Authentication and Authorization: Mastering Security
  • Authentication With Remote LDAP Server in Spring WebFlux
  • Authentication With Remote LDAP Server in Spring Web MVC
  • How to Implement Two-Factor Authentication in A Spring Boot OAuth Server? Part 2: Under the Hood

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: