Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Spring Security Context

The Spring Security Context is a powerful feature that holds the security information of the current user. This guide covers key concepts and steps for working with the Security Context in your Spring Boot application, including adding dependencies, accessing the Security Context, and configuring security settings.

Key Concepts of Security Context

  • Security Context: Holds the security information of the current user, including their authentication details and granted authorities.
  • Authentication: Represents the principal and credentials of the current user.
  • Security Configuration: Configuring Spring Security to manage the Security Context.

Adding Dependencies

Include the Spring Security dependency in your pom.xml file:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Accessing the Security Context

Access the Security Context in your application to get information about the current user:

Example: Accessing the Security Context in a Controller

// MyController.java
package com.example.myapp.controller;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/current-user")
    public String currentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return "Current user: " + authentication.getName();
    }
}

Configuring Security

Ensure Spring Security is configured to manage the Security Context:

Example: SecurityConfiguration.java

// SecurityConfiguration.java
package com.example.myapp.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/home", true)
            .failureUrl("/login?error=true")
            .and()
            .logout()
            .logoutSuccessUrl("/login?logout=true")
            .permitAll();
    }
}

Accessing User Details

Access additional user details such as roles and authorities:

Example: Accessing User Details in a Controller

// MyController.java
package com.example.myapp.controller;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;

@RestController
public class MyController {

    @GetMapping("/user-details")
    public String userDetails() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        Collection authorities = authentication.getAuthorities();
        return "User: " + username + ", Roles: " + authorities.toString();
    }
}

Setting the Security Context Manually

In some cases, you might need to set the Security Context manually:

Example: Setting the Security Context in a Service

// MyService.java
package com.example.myapp.service;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import java.util.Collections;

@Service
public class MyService {

    public void authenticateUser(String username) {
        UserDetails userDetails = User.withUsername(username).password("").authorities(Collections.emptyList()).build();
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
}

Testing the Security Context

Test the Security Context using Spring Security's test support:

Example: SecurityTests.java

// SecurityTests.java
package com.example.myapp;

import com.example.myapp.config.TestSecurityConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest
@Import(TestSecurityConfig.class)
public class SecurityTests {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithMockUser(username = "user", roles = {"USER"})
    public void testCurrentUser() throws Exception {
        mockMvc.perform(get("/current-user"))
                .andExpect(status().isOk())
                .andExpect(content().string("Current user: user"));
    }
}

Key Points

  • Security Context: Holds the security information of the current user, including their authentication details and granted authorities.
  • Authentication: Represents the principal and credentials of the current user.
  • Security Configuration: Configuring Spring Security to manage the Security Context.
  • Include the Spring Security dependency in your pom.xml file.
  • Access the Security Context in your application to get information about the current user.
  • Ensure Spring Security is configured to manage the Security Context.
  • Access additional user details such as roles and authorities.
  • Set the Security Context manually when necessary.
  • Test the Security Context using Spring Security's test support.

Conclusion

Working with the Security Context in Spring Security is essential for managing and accessing the security information of the current user. By understanding and implementing Security Context access, configuration, and testing, you can ensure that your Spring Boot application handles security information effectively and securely. Happy coding!