A Complete Guide To Spring Security With SpringBoot - by Satya Kaveti - Medium
A Complete Guide To Spring Security With SpringBoot - by Satya Kaveti - Medium
Listen Share
SpringBoot — Security
Spring Boot supports several authentication types to secure your application. Here
are the most commonly used authentication types:
2. OAuth2: OAuth2 is an open standard for authorization that allows users to grant
third-party applications access to their resources without giving them their
credentials. Spring Boot provides OAuth2 support using the Spring Security
OAuth2 module.
3. JWT Authentication (JSON Web Tokens ): JSON Web Tokens are a secure way to
transmit information between parties as a JSON object. JWTs are commonly
used for authentication and authorization purposes in modern web applications.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 1/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
These are just some of the authentication types supported by Spring Boot.
Depending on the requirements of your application, you can choose the appropriate
authentication type or even combine multiple types to provide a more secure and
flexible authentication mechanism.
1. When ever user request Rest API with username & password, request goes to
Authentication Filter
2. The AuthenticationFilter is a servlet filter class that will see if the user has
already authenticated or not. If not, it will send that request to the
AuthenticationManager to check if the details sent by the user is valid or not.
4. The Authentication Provider will not fetch the user details from the database or
from LDAP or in memory. It will use UserDetailsService & PasswordEncoder for
that purpose.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 2/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
SecurityContext VS JSESSIONID
For the first time the authentication happens, the JSESSIONID is created & stores
inside of the SecurityContext as JSessionID as key & all the authentication
information as value.
from next time as the client sends in the JSESSIONID, AuthenticationFilter uses that
JSESSIONID checks if he’s already authenticated. And it will not prompt for
authentication as long as that cookie is available. And when you deleted it, it will ask
for the authentication again.
Going Deep…
Create a Sample SpringBoot Project & add Maven Dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
So you go along, add Spring Security to your Spring Boot (or plain Spring) project
and suddenly…
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 3/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
At its core, Spring Security is really just a bunch of servlet filters that help you add
[authentication] and [authorization] to your web application.
It also integrates well with frameworks like Spring Web MVC (or Spring Boot), as
well as with standards like OAuth2 or SAML. And it auto-generates login/logout
pages and protects against common exploits like CSRF.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Run the Application & you can see the default security password on the console
Let’s Hit Any API. You will get unauthorized response.Select Basic Auth from
Postman, fill details & hit again
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 4/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
@EnableWebSecurity
@Configuration
public class DefaultSecurityConfig {
@Bean
@ConditionalOnMissingBean(UserDetailsService.class)
InMemoryUserDetailsManager inMemoryUserDetailsManager() {
String generatedPassword = // ...;
return new InMemoryUserDetailsManager(User.withUsername("user")
.password(generatedPassword).roles("ROLE_USER").build());
}
@Bean
@ConditionalOnMissingBean(AuthenticationEventPublisher.class)
DefaultAuthenticationEventPublisher defaultAuthenticationEventPublisher(App
return new DefaultAuthenticationEventPublisher(delegate);
}
}
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 5/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Now Lets implement our own Authentication mechanism . Steps involved for
implementing our own Security Configuration
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Ex
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/empapp/api/v1/**").authenticated() // Secure pa
.anyRequest().permitAll() // Allow other requests
.and()
.httpBasic().and()
.formLogin().and().csrf().disable();;
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails userDetails = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
@Bean
public AuthenticationManager authenticationManager(UserDetailsService userD
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticatio
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder);
return new ProviderManager(authenticationProvider);
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 6/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
Here
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 7/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Now we got some idea about Spring Security & move forward..
1. Authentication
First off, if you are running a typical (web) application, you need your users to
authenticate. That means your application needs to verify if the user is who he claims
to be, typically done with a username and password check.
2. Authorization
Most applications have the concept of permissions (or roles). Imagine: customers
who have access to the public-facing frontend of your webshop, and administrators
who have access to a separate admin area.
3. Servlet Filters
Last but not least, let’s have a look at Servlet Filters
Basically any Spring web application is just one servlet: Spring’s good old
DispatcherServlet, that redirects incoming HTTP requests (e.g. from a browser) to
your @controllers or @RestControllers.
The thing is: There is no security hardcoded into that DispatcherServlet and you also
very likely don’t want to fumble around with a raw HTTP Basic Auth header in your
@controllers. Optimally, the authentication and authorization should be done before
a request hits your @controllers.
Luckily, there’s a way to do exactly this in the Java web world: you can put filters in
front of servlets, which means you could think about writing a SecurityFilter and
configure it in your Tomcat (servlet container/application server) to filter every
incoming HTTP request before it hits your servlet.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 8/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
In the real-world, however, you would split this one filter up into multiple filters, that
you then chain together.
This concept is called FilterChain and the last method call in your filter above is
actually delegating to that very chain:
chain.doFilter(request, response);
Let’s assume you [set up Spring Security] correctly and then boot up your web
application. You’ll see the following log message:
If you expand that one line into a list, it looks like Spring Security does not just
install one filter, instead it installs a whole filter chain consisting of 15 (!) different
filters.
So, when an HTTPRequest comes in, it will go through all these 15 filters, before
your request finally hits your @RestControllers. The order is important, too, starting
at the top of that list and going down to the bottom.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 9/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
So with these couple of filters, Spring Security provides you a login/logout page, as
well as the ability to login with Basic Auth or Form Logins, as well as a couple of
additional goodies like the CsrfFilter.Those filters, for a large part, are Spring
Security. Hence, we need to have a look at how to configure Spring Security, next.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.csrf().disable()
.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception
{
auth.inMemoryAuthentication()
.withUser("admin")
.password("{noop}password")
.roles("ROLE_USER");
}
}
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 10/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr25
public class SecurityConfig {
// config
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
.antMatchers(HttpMethod.DELETE)
.hasRole("ADMIN")
.antMatchers("/admin/**")
.hasAnyRole("ADMIN")
.antMatchers("/user/**")
.hasAnyRole("USER", "ADMIN")
.antMatchers("/login/**")
.anonymous()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 11/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
@Bean
public UserDetailsService userDetailsService(BCryptPasswordEncoder bCryptPasswo
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user")
.password(bCryptPasswordEncoder.encode("userPass"))
.roles("USER")
.build());
manager.createUser(User.withUsername("admin")
.password(bCryptPasswordEncoder.encode("adminPass"))
.roles("USER", "ADMIN")
.build());
return manager;
}
@Bean
public AuthenticationManager authenticationManager(HttpSecurity http, BCryptPas
throws Exception {
return http.getSharedObject(AuthenticationManagerBuilder.class)
.userDetailsService(userDetailsService)
.passwordEncoder(bCryptPasswordEncoder)
.and()
.build();
}
———————INTERVAL————————-
(take a break & comeback…much more coming )
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 12/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Authentication Types
When it comes to authentication and Spring Security you have roughly three
scenarios:
1. The default: You can access the (hashed) password of the user, because you have
his details (username, password) saved in e.g. a InMenory, Basic, database table.
2. Less common: You cannot access the (hashed) password of the user. This is the
case if your users and passwords are stored somewhere else, like in a 3rd party
identity management product offering REST services for authentication. Think:
Atlassian Crowd.
Note: Depending on your scenario, you need to specify different @Beans to get
Spring Security working, otherwise you’ll end up getting pretty confusing
exceptions (like a NullPointerException if you forgot to specify the
PasswordEncoder). Keep that in mind
1.Basic Authentication
Basic Authentication is a simple authentication scheme that sends the user’s
credentials in the header of each request.
Basic authentification is a standard HTTP header with the user and password
encoded in base64 : Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== .The
1. Maven Dependency.
The simplest way to add all required jars is to add the latest version of spring-boot-
starter-security dependency.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 13/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.csrf().disable()
.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception
{
auth.inMemoryAuthentication()
.withUser("admin")
.password("{noop}password")
.roles("ROLE_USER");
}
}
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 14/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
@Configuration
public class BasicAuthWebSecurityConfiguration
{
@Autowired
private AppBasicAuthenticationEntryPoint authenticationEntryPoint;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User
.withUsername("user")
.password(passwordEncoder().encode("password"))
.roles("USER_ROLE")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(8);
}
}
For demo purposes, we can write a simple REST API given below.
EmployeeController.java
@RestController
@RequestMapping(path = "/employees")
public class EmployeeController
{
@Autowired
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 15/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Upon passing authorization request header with encoded basic-auth user name and
password combination, we will be able to access the rest api response. Access rest
api at URL: HTTP GET http://localhost:8080/employees/
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 16/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
This is as simple as getting an instance of the Base64.Encoder and input the string as
bytes to encode it.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 17/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Output
dXNlcm5hbWU6cGFzc3dvcmQ=
This is also very simple. Just get the instance of Base64.Decoder and use it to decode
the base 64 encoded string.
Output
username:password
create table users (id int auto_increment primary key, username varchar(255), p
In this case Spring Security needs you to define two beans to get authentication up
and running.
1. A UserDetailsService.
2. A PasswordEncoder.
@Bean
public UserDetailsService userDetailsService() {
return new MyDatabaseUserDetailsService(); // (1)
}
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 19/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
String getPassword();
// <3> more methods:
// isAccountNonExpired,isAccountNonLocked,
// isCredentialsNonExpired,isEnabled
}
1. A UserDetailsService loads UserDetails via the user’s username. Note that the
method takes only one parameter: username (not the password).
2. The UserDetails interface has methods to get the (hashed!) password and one to
get the username.
3. UserDetails has even more methods, like is the account active or blocked, have
the credentials expired or what permissions the user has — but we won’t cover
them here.
So you can either implement these interfaces yourself, like we did above, or use
existing ones that Spring Security provides.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 20/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
1. Extract the username/password combination from the HTTP Basic Auth header
in a filter. You don’t have to do anything for that, it will happen under the hood.
3. Take the extracted password from the HTTP Basic Auth header, hash it
automatically and compare it with the hashed password from your UserDetails
object. If both match, the user is successfully authenticated.
That’s all there is to it. But hold on, how does Spring Security hash the password
from the client (step 3)? With what algorithm?
PasswordEncoders
Spring Security cannot magically guess your preferred password hashing algorithm.
That’s why you need to specify another @Bean, a PasswordEncoder. If you want to,
say, use the BCrypt password hashing function (Spring Security’s default) for all your
passwords, you would specify this @Bean in your SecurityConfig.
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
What if you have multiple password hashing algorithms, like Bcrypt or SHA-256?
Then you would use the following encoder:
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 21/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
1. Read in those passwords and strip off the prefix ( {bcrypt} or {sha256} ).
3. Hash the incoming, raw password with that PasswordEncoder and compare it
with the stored one.
Here, You do not have the user passwords anymore in your application, you have a
REST API that you can login against, with your username and password. (A POST
request to the */rest/usermanagement/1/authentication* REST endpoint).
If that is the case, you cannot use a UserDetailsService anymore, instead you need to
implement and provide an AuthenticationProvider @Bean.
@Bean
public AuthenticationProvider authenticationProvider() {
return new AtlassianCrowdAuthenticationProvider();
}
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 22/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
1. Compared to the UserDetails load() method, where you only had access to the
username, you now have access to the complete authentication attempt, usually
containing a username and password.
2. You can do whatever you want to authenticate the user, e.g. call a REST-service.
Let’s now have a look at permissions, or rather roles and authorities in Spring
Security
An authority (in its simplest form) is just a string, it can be anything like: user,
ADMIN, ROLE_ADMIN or 53cr37_r0l3.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 23/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
A role is an authority with a *ROLE_* prefix. So a role called *ADMIN* is the same
as an authority called *ROLE_ADMIN* .
The distinction between roles and authorities is purely conceptual and something
that often bewilders people new to Spring Security.
@Override
public String getAuthority() {
return role;
}
}
We are storing the users in Users table.Now, you would simply add a column called
“authorities” to it.adding could contain multiple, comma-separated values
authorities.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 24/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin").hasAuthority("ROLE_ADMIN") // (1)
.antMatchers("/callcenter").hasAnyAuthority("ROLE_ADMIN", "ROLE_CAL
.anyRequest().authenticated() // (3)
.and()
.formLogin()
.and()
.httpBasic();
}
}
1. To access the */admin* area you (i.e. the user) need to be authenticated AND
have the authority (a simple string) ROLE_ADMIN.
2. To access the */callcenter* area you need to be authenticated AND have either
the authority ROLE_ADMIN OR ROLE_CALLCENTER.
3. For any other request, you do not need a specific role but still need to be
authenticated.
How can the resource owner (you) give a client (3rd party software) scoped access (read or
write or both) to a protected resource (bank account)?
The *resource owner* is you, the user, who holds the rights to something.
The 3rd party application, who wants to access the *protected resource* in your
place, is called the *client* . Never confuse the *client* with the *resource
owner* .
(Additionally, the client only gets *scoped* access, i.e. it can only read
transactions in this example)
These are three main players of every OAuth interaction. The main goal of the
OAuth 2.0 flow is for the client to get a valid access token.
In our banking example, the protected resource (bank account) and authorization
server would both be provided by the bank. It could be two different systems, or the
same system with two different endpoints.
Client — the application (user is using) which require access to user data on the
resource server.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 26/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Resource Server — store user’s data and http services which can return user data
to authenticated clients.
The refresh token is issued (along with the access token) to the client by the
authorization server, and it is used to obtain a new access token when the current
access token becomes invalid or expires.
The responsibility of refresh token is to request for a new access token when the
existing access token is expired.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 27/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 28/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
After the application has been created, note down the generated client id and client
secret.
spring:
security:
oauth2:
client:
registration:
github:
client-id: 01cbd1fd06e10fe0da41
client-secret: f116116a4cee00c46993d14859912XXXXXXXXX
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 29/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/swagger/*").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login();
return http.build();
}
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 30/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Here are the steps to create a custom authentication provider for OAuth in Spring
Boot:
@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserReq
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Auth
// TODO: Implement your custom OAuth2 authentication logic here
return null;
}
}
1. Implement the loadUser() method to load the user details from the OAuth
provider. This method should return an instance of OAuth2User that contains the
user's details.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomOAuth2UserService customOAuth2UserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login()
.userInfoEndpoint()
.userService(customOAuth2UserService);
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 31/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
}
}
With these steps, you can create a custom authentication provider for OAuth in
Spring Boot and use it to authenticate users in your application.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 32/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Here are the steps to create a Spring Boot application with pre-authentication using
Spring Security:
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
return request.getHeader("X-USERID");
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request)
return "N/A";
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomPreAuthenticatedProcessingFilter customPreAuthenticatedProces
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilter(customPreAuthenticatedProcessingFilter)
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic().disable()
.csrf().disable();
}
@Override
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 33/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
2. Start your application and make a request with the user’s authentication
information in the request header. In this example, we’re using the X-USERID
With these steps, you can implement pre-authentication using Spring Security in
your Spring Boot application. When a user makes a request with their
authentication information in the request header, the custom filter extracts the
information and passes it to Spring Security’s authentication mechanism, which can
authenticate the user based on the identity.
Sample Implemetation
/**
* Security configuration based on the Spring Security setup.
* <p>
* Since Micro-Services do not participate in authentication of users, and the
* to an external Authentication Server, then this configuration wires the Pre-
* to extract the authenticated user token from the header.
* <p>
* By default, all APIs at path /api will be secured against the pre-authentica
*
*
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception
// Configure Security Policy
http
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 34/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
@Bean
public AuthenticationProvider authenticationProvider() {
PreAuthenticatedAuthenticationProvider authenticationProvider = new Pre
authenticationProvider.setPreAuthenticatedUserDetailsService(this.userD
// Turn off exceptions since we have configured a 403 for the security
authenticationProvider.setThrowExceptionWhenTokenRejected(false);
return authenticationProvider;
}
@Bean
public AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken
return new AuthorizationUserDetailsService();
}
}
/**
* Spring Security UserDetails Service class for pre-authenticated requests.
* <p>
* Pre-authenticated requests inject a header token of the user id that has alr
* by an external Authentication Server.
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 35/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
* <p>
* This class is responsible for applying verification of the token and loading
* roles. No authentication is actually performed here
*
*/
@Slf4j
public class AuthorizationUserDetailsService implements AuthenticationUserDetai
/**
* Load and return a UserDetails instance of the Pre-Autenticated user token.
* <p>
* Caching is enabled here since the Security Config is Stateless (SessionCrea
* then there is no session management, which can cause performance issues due
* new Security Context for every request.
* <p>
* NOTE: Ensure the caching configuration declares the Cache name of <b>PreAut
*
*/
@Override
@Cacheable(value = "PreAuthUsers", key = "#token")
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
String userId = token.getCredentials().toString();
log.debug("Detected Pre-Authenticated token for user: {}", userId);
Ref.
I have gone through below articles while writing this post. So this post not completly
wrote by me. https://www.marcobehler.com/guides/spring-
security#_authentication_with_spring_security
https://www.marcobehler.com/guides/spring-security-oauth2
https://howtodoinjava.com/spring-boot2/oauth2-auth-server/
https://howtodoinjava.com/spring-security/oauth2-login-with-spring-boot-security/
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 36/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Follow
I am Satya Kaveti, Java Full Stack Developer from Hyderabad, India. My articles will be Short and Sharp.
Satya Kaveti
8 1
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 37/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Satya Kaveti
Satya Kaveti
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 38/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Spring Boot using @Scheduled annotation for Task Scheduling. The @Scheduled annotation is
added to a method along with some information…
11
Satya Kaveti
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 39/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Satya Kaveti
Bubu Tripathy
DTO-Free Java
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 40/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
259 13
Lists
Staff Picks
587 stories · 770 saves
Open in app Sign up Sign in
Search
Dilanka Wijesekara
65
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 41/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Kostiantyn Illienko
241
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 42/43
23/02/2024, 19:44 A Complete Guide to Spring Security with SpringBoot | by Satya Kaveti | Medium
Suvesh Agnihotri
82
Berktorun
93
https://satyacodes.medium.com/a-complete-guide-to-spring-security-with-springboot-329a959a7c64 43/43