Spring security provides authentication an authorisation.
Spring Security is a security framework for Java and Spring Boot applications.
It provides:
Authentication → verifying user identity
Authorization → controlling access
Session management
Password encryption
CSRF protection
JWT/OAuth2 support
Spring security will be enabled after adding below XML defintions in POM.xml.
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-security-test
test
Spring security filters almost all pages except the pages which is marked to permit and gives login page.
Type 1:
Passwor will be automatically generate in devleoper tool console and user will be user.
This password will be changedd on each application bootup.
Flow :
http://localhost:8080/First/add/6/8
when the user clicks this link, instead of displaying output a login page will be shown, this is prewritten and plugged in using xml definition. the actual output of addition will be displayed after authentication.
Type:2
Adding our own username and password in application properties.
spring.security.user.name=admin
spring.security.user.password=generate
Now application will not generate password but a login page will be shown on clicking the addition endpoint.
User has to enter correct username and password mentioned in application.properties. After authenticating him, he will be redirected to the output page,else error with status code 403 will be displayed
Type3:
Adding multiple users.
we cannot add all users in property file. Though property file will not accept adding duplicate properties, in real time we will be having huge data and adding in property or convincing it to accept is not an idea.
So we can achieve this multiple user concept in spring security using UserDetailsManager Interface. Its implementation class is InMemoryUserDetailsManager.
This accepts a list with userDetails objects.
UserDetails is a static method with methods to add username,password,roles etc.
Here is the code snippet:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@bean
public UserDetailsManager createUserDetailsManager(){
UserDetails user1= User.withUsername("Sri").password("{noop}generate").roles("admin").build();
UserDetails user2=User.withUsername("Desigan").password("{noop}generate").roles("user").build();
// Add users to the UserDetailsManager
List l = Arrays.asList(user1, user2);
UserDetailsManager userDetailsManager = new InMemoryUserDetailsManager(l);
return userDetailsManager;
}
Authorisation:
It works based on user privilages.
User with admin access can see all pages.
User with read access can view pages but he cannot make any changes.
we can set these privilages in security config class.
@bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// Disable CSRF (useful for REST APIs)
.csrf(csrf -> csrf.disable())
// Authorization rules
.authorizeHttpRequests(auth -> auth
.requestMatchers("/calc/add/**").permitAll() // No auth required
.requestMatchers("/calc/sub/**").hasRole("USER")
.requestMatchers("/calc/mul/**").hasRole("ADMIN")
.requestMatchers("/calc/div/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults());
return http.build();
}
In above snippet ".permitAll()" allows the user to view endpoint without any authentication.
For all the requestMatchers("/div/").hasRole("user") -> user with User role will be able to view this page.
**Option 2: JDBCUserDetialsManager.
It is nothing but communicating with database to perform login.
It has four steps, 1. collect data from UI 2. Request Database for UserDetails using loadByUserName(username) method from UserDetailService interface.
- compare data from UI with data from DB
- Provide success or failure login based on the results from above step. To achieve this we need load data into DB first, This is what we call as "SIGNUP". Im going to write an endpoint and send a request from POSTMan and load data into Database. This request again pass through Spring security firewall check. To allow our request to endpoint we can request spring security to permit our endpoint URL by adding below line.
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/error").permitAll()
.requestMatchers("/First/signUp/**").permitAll()
.anyRequest().authenticated())
.formLogin(Customizer.withDefaults());
// .httpBasic(Customizer.withDefaults());
return http.build();
}
Controller:
@RequestMapping("/signUp")
////@ResponseBody
public ResponseEntity processUserSignUp(@RequestBody User user ){
log.info("inside LearningFrontController.getmultiplyService");
response=calculatorService.processUserSignUp(user);
log.info(response);
if(response.equalsIgnoreCase("success")){
return ResponseEntity.status(200).body(response);
}
log.info("exiting LearningFrontController.getmultiplyService");
return ResponseEntity.status(400).body("Signup failed");
}
Service:
public String processUserSignUp(User user){
String response="failed";
UserDetailsEntity userDetailsEntity = new UserDetailsEntity();
userDetailsEntity.setUserName(user.getUserName());
String maskedPassword=passwordEncoder.encode(user.getPassword());
userDetailsEntity.setMaskedPassword(maskedPassword);
userDetailsEntity.setUserRole(user.getRoles());
UserDetailsEntity userDetailsEntity1= customUserDetailsRepo.save(userDetailsEntity);
if(userDetailsEntity1!=null) {
return "success";
}
return response;
}
JSON:
{
"userName":"Sri",
"Password":"generate",
"roles":"User"
}
What we have in table?
UserNo PAssword userName Role
202 $2a$10$PtbhgrteGOLk0azcyGK1x SriKamini USER
203 $2a$10$WcefaBSrdqTIqLLOAh3XNep Sri USER
Top comments (0)