CUSTOMISED
Expert-led training for your team
Dismiss
Securing Microservices with Spring Security

6 September 2023

Securing Microservices with Spring Security

Microservices provide great flexibility in building complex applications, but securing them brings unique challenges. With multiple independent services, you need to think about security at the architecture level in addition to the implementation in individual services.

In this guide, we'll look at various options for securing microservices using the widely adopted Spring Security framework.

JBI Training is the perfect place to start your journey why not enquire about out  Spring Boot Microservices training: Master the art of building microservices with Spring Boot. Understand how to create efficient, production-ready microservices using the Spring framework, enabling rapid development and deployment.

Microservices Security Challenges

Some key security challenges with microservices:

  • Authentication and authorization - How to handle sign-on and access control across services?
  • Network security - How to secure service-to-service communication?
  • Key management - How to safely distribute and rotate security keys?
  • Monitoring - How to monitor identity management and detect threats?

Traditional monolithic applications have a single authentication and authorization system like a session-based cookie. But microservices require decoupled security mechanisms to authenticate across multiple domains.

Microservice endpoints are exposed on the network, requiring service-to-service calls to be secured. Centralized key management is also more difficult with independent services.

By thinking about these needs up front, we can design appropriate security into our architecture.

Securing Microservices with Spring Security

Spring Security provides comprehensive security capabilities for Spring-based applications. It supports both authentication at the web request level and authorization to restrict access to specific resources.

Some key features:

  • HTTP security headers, CSRF protection
  • Stateless authentication with JWT tokens
  • Role and permission-based access control
  • Password encoding, DAO authentication
  • Integration with OAuth2, OpenID Connect

We'll cover how these can be applied to common microservices security requirements.

Authentication and Authorization

A core requirement is being able to authenticate users across multiple services and authorize access to specific endpoints and data.

Cross-Service Authentication

For user sign-on across services, Spring Security supports stateless JWT (JSON Web Token) authentication.

The auth service signs and issues JWT tokens upon successful authentication. Other services can then validate the JWT signature to authenticate requests. No shared session state is required.

Configure Spring Security to use JWT:


@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
      .anyRequest().authenticated()
      .and()
      .oauth2ResourceServer()
      .jwt();
  }
}

The jwt() configures JWT validation. The token can be passed in the Authorization header.

Role-based Authorization

To restrict access, services can check authorities or roles embedded in the JWT claims.

 
http
  .authorizeRequests()
    .antMatchers("/admin").hasRole("ADMIN")
    .anyRequest().authenticated();

This requires the "ADMIN" role to access /admin endpoints.

Roles and claims can also be checked in method security:


@PreAuthorize("hasAuthority('ROLE_ADMIN')")
public void adminTask() {
  // ...
} 

OAuth2 Integration

Spring Security provides tight integration with OAuth2 authorization servers like Okta or Auth0 for authentication.

Rather than implementing a custom auth service, you can delegate to an external OAuth2 provider.

Configure a OAuth2LoginConfig to enable OAuth2 login:


@EnableWebSecurity
public class OAuth2LoginConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .anyRequest().authenticated()
        .and()
      .oauth2Login();
  }
}

User info is fetched from the provider to perform authentication. No session or tokens are maintained by the app.

Network Security

Since microservices communicate over the network, we need to secure those service-to-service calls.

Transport Layer Security (TLS)

Enable TLS in Spring Security to encrypt all traffic:


@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      // ...
      
      .requiresChannel()
        .anyRequest().requiresSecure();
  }
}

requiresSecure() enforces HTTPS for all requests.

Service-to-service calls should always use TLS to prevent eavesdropping or man-in-the-middle attacks.

Service Authentication

Individual services can be authenticated to each other through certificates or shared keys.

For example, a certificate can be generated for each service and packaged in its Docker image. Other services validate the certificate when calling that service.

Spring Security can validate the certificate and authenticate the calling service:


@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    // ...

    http.x509()
      .subjectPrincipalRegex("CN=(.*)")
      .userDetailsService(customUserDetails);
  }
}

The subject principal is extracted from the cert as the user. A custom UserDetailsService can then load authorities for authorization.

Client-Side Load Balancing

With multiple service instances, clients need to load balance across them.

Spring Cloud LoadBalancer can create a client-side load balancer:


@Bean
LoadBalancerClient loadBalancerClient() {
  return new LoadBalancerClient(); 
}

@Bean
RestTemplate restTemplate(LoadBalancerClient loadBalancerClient) {
  return new RestTemplate(loadBalancerClient);  
}

The LoadBalancerClient automatically distributes calls based on service discovery registrations.

Centralized Key Management

Microservices also bring challenges for managing security credentials like keys and certificates.

To simplify key distribution, a centralized service like HashiCorp Vault can be used to generate and rotate keys. Services request keys on startup and renew periodically.

Spring Cloud Vault Sec integrates with HashiCorp Vault for fetching secrets:


@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Value("${vault.token}")
  String vaultToken;
  
  @Bean
  VaultTemplate vaultTemplate() {
    return new VaultTemplate(vaultToken);
  }

  @Bean
  @DependsOn("vaultTemplate")
  DataSource dataSource() {
    VaultResponse response = vaultTemplate.read("secret/myapp/config");

    return DataSourceBuilder.create()
      .username(response.getData().get("username"))
      .password(response.getData().get("password"))
      .url(response.getData().get("url"))
      .driverClassName("com.mysql.jdbc.Driver")
      .build();
  }  
}

Here the Datasource credentials are externalized to Vault secrets. Services access Vault through the VaultTemplate to securely obtain secrets at runtime.

Monitoring and Audit

Finally, we need visibility into how users and services are accessing our systems.

Spring Security provides events for login success/failure that can be used to track authentication activity.


@Component
public class AuthenticationEventsHandler {

  @EventListener
  public void authenticationSuccess(AuthenticationSuccessEvent event) {
    // Handle login success
  }

  @EventListener(AuthenticationFailureBadCredentialsEvent.class)
  public void authenticationFailed(AuthenticationFailureBadCredentialsEvent event) {
    // Handle login failure
  }
}

These events can be used with monitoring tools to identify suspicious patterns or security incidents.

Access logs also provide audit visibility into authorization failures - requests for data a user can't access. These can indicate compromised credentials or insider threats.

Conclusion

Securing microservices introduces challenges like cross-service authentication, network encryption, and distributed credentials.

Spring Security provides authentication, authorization, TLS, integration with external Identity providers, and events to address these needs.

Centralised user management, service-to-service authentication, and runtime secret injection help overcome distributed security complexities.

Monitoring authentication events and access logs gives visibility into compromised users or services.

Adopting these patterns will help build secure and resilient microservices powered by Spring.

In the world of modern software development, Microservices Architecture stands as a pivotal paradigm for building scalable and maintainable applications. Explore our range of courses at JBI Training, each tailored to empower you with the skills to excel in the realm of microservices and software architecture. You might enjoy our previous article How to Build Microservices with Spring Boot Step-by-Step Guide or consider some of our training. 

  • Microservices Architecture: Delve into the core principles and practices of microservices architecture. Learn how to design, deploy, and manage microservices-based systems, fostering agility and scalability in your applications.
  • Spring Boot Microservices training: Master the art of building microservices with Spring Boot. Understand how to create efficient, production-ready microservices using the Spring framework, enabling rapid development and deployment.
  • Micro Frontends: Explore the world of micro frontends, a complementary concept to microservices. Learn how to create modular frontend applications that align with the principles of microservices architecture, enhancing flexibility and maintainability.
  • Software Architecture: Deepen your understanding of software architecture principles. Gain insights into architectural patterns, design principles, and best practices that underpin successful software systems, including microservices.
  • AWS for Developers: Discover how to leverage AWS (Amazon Web Services) to support your microservices-based applications. Learn to deploy, scale, and manage microservices on AWS, harnessing the power of cloud computing for your development needs.

Enrol in these courses and empower yourself to navigate the dynamic world of microservices architecture and software development. Equip yourself with the tools and knowledge to design, build, and manage microservices-based systems that excel in scalability, flexibility, and performance.

About the author: Daniel West
Tech Blogger & Researcher for JBI Training

CONTACT
+44 (0)20 8446 7555

[email protected]

SHARE

 

Copyright © 2023 JBI Training. All Rights Reserved.
JB International Training Ltd  -  Company Registration Number: 08458005
Registered Address: Wohl Enterprise Hub, 2B Redbourne Avenue, London, N3 2BS

Modern Slavery Statement & Corporate Policies | Terms & Conditions | Contact Us

POPULAR

Rust training course                                                                          React training course

Threat modelling training course   Python for data analysts training course

Power BI training course                                   Machine Learning training course

Spring Boot Microservices training course              Terraform training course

Kubernetes training course                                                            C++ training course

Power Automate training course                               Clean Code training course