1️⃣ Project Structure
spring-security-demo/
├── lib/ # Put all Spring Boot JARs here
├── src/
│ └── main/
│ └── java/
│ └── com/example/demo/
│ ├── DemoApplication.java
│ ├── SecurityConfig.java
│ ├── UserController.java
│ └── CustomUserDetailsService.java
2️⃣ DemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
3️⃣ SecurityConfig.java
package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final CustomUserDetailsService userDetailsService;
public SecurityConfig(CustomUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.and()
.logout()
.permitAll();
return http.build();
}
@Bean
public AuthenticationManager authManager(HttpSecurity http) throws Exception {
return http.getSharedObject(AuthenticationManagerBuilder.class)
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder())
.and()
.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
4️⃣ CustomUserDetailsService.java
package com.example.demo;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// In-memory users (you can replace this with DB)
if ("admin".equals(username)) {
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return new User("admin", new BCryptPasswordEncoder().encode("admin123"), authorities);
} else if ("user".equals(username)) {
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new User("user", new BCryptPasswordEncoder().encode("user123"), authorities);
} else {
throw new UsernameNotFoundException("User not found");
}
}
}
5️⃣ UserController.java
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/user/info")
public String userInfo() {
return "User Content: Accessible by USER or ADMIN";
}
@GetMapping("/admin/info")
public String adminInfo() {
return "Admin Content: Accessible by ADMIN only";
}
@GetMapping("/public/info")
public String publicInfo() {
return "Public Content: Accessible by anyone";
}
}
6️⃣ Running without Maven/Gradle
- Put all required Spring Boot JARs and dependencies in a
lib/
folder. - Compile Java files:
javac -cp "lib/*" -d out src/main/java/com/example/demo/*.java
- Run the application:
java -cp "out:lib/*" com.example.demo.DemoApplication
Windows users: replace
:
with;
in classpath.
✅ Features included:
- Form-based login
- Role-based access (
USER
vsADMIN
) - BCrypt password encoding
- Public and protected endpoints
- Custom
UserDetailsService
(can be replaced with database)