Write and Publish a Tutorial!
Do you have good notes or papers written by you and seeking for a
platform to publish? We provide the platform to publish your tutorials
in your name. If you wish to publish your tutorial in your name to
help the readers, Please contact us by sending an email to
publish@tools4testing.com or publish@java4coding.com The main way that
others learn about your work is through your published tutorials. If
you don’t publish, it will be as if you never did the work. Your notes
can help the readers only when you share it.
How to override Spring security default configurations
The default configuration of Spring Security incorporates the UserDetailsService and PasswordEncoder. The UserDetailsService interface within Spring Security oversees user details, while the PasswordEncoder is responsible for encoding passwords and verifying their match with existing encodings. In cases where we substitute the default UserDetailsService implementation, it is imperative to explicitly specify PasswordEncoder to maintain a seamless and secure authentication setup.
You can create your own beans of UserDetailsService and PasswordEncoder or can use an implementation provided by Spring Security.
In our scenario, we are overriding the default configuration by employing the InMemoryUserDetailsManager and NoOpPasswordEncoder. The InMemoryUserDetailsManager stores credentials in memory, serving as a convenient tool for authentication in non-production settings, such as examples or proof of concepts.
While the InMemoryUserDetailsManager is not recommended for production-ready applications, it provides a straightforward way to manage users without the need for elaborate implementation.
The NoOpPasswordEncoder used here treats passwords as plain text without encryption or hashing. It's important to note that this approach is not suitable for production environments. NoOpPasswordEncoder is marked as deprecated, and its usage is discouraged due to security considerations. However, in educational or illustrative contexts, it can be helpful for understanding the basics of password matching without delving into hashing algorithms.
pom.xml<?xml version="1.0" encoding="UTF-8"?> <project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.0</version> <relativePath/> <!-- lookup parent from repository, not local --> </parent> <groupId>com.example</groupId> <artifactId>InMemoryUserDetailsManagerAndNoOpPasswordEncoder</artifactId> <version>0.0.1-SNAPSHOT</version> <name>InMemoryUserDetailsManagerAndNoOpPasswordEncoder</name> <description>Spring Boot Security Auto-Configuration</description> <properties> <java.version>11</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.6.0</spring-boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <executions> <execution> <id>build-info</id> <goals> <goal>build-info</goal> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
</project> |
ApplicationConfig.javapackage com.java4coding;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration public class ApplicationConfig { @Bean public UserDetailsService userDetailsService() { var userDetailsService = new InMemoryUserDetailsManager(); var user = User.withUsername("manu") .password("abcd") .authorities("read") .build(); userDetailsService.createUser(user); return userDetailsService; }
@Bean public PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } } |
DemoController.javapackage com.java4coding;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;
@RestController public class DemoController {
@GetMapping(value = "/demo") public String sayHello() { return "Hurray! You are Authorized."; } } |
SpringBootDemo.javapackage com.java4coding;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication public class SpringBootDemo { public static void main(String[] args) { SpringApplication.run(SpringBootDemo.class, args); } } |
Let’s try the endpoint with the new user having the username manu and the password abcd: