<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
Create Role enum in package model
public enum Role {
Admin,
User
}
Create class Member in package model
public class Member {
private String id;
private String email;
private String password;
private Role role;
public Member(String id, String email, String password, Role role) {
this.id = id;
this.email = email;
this.password = password;
this.role = role;
}
}
Create MemberService in package service
@Service
public class MemberService implements UserDetailsService {
@Autowired
MemberRepository repository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Member member = repository.findByEmail(username);
if(member == null){
return null;
}
return User.withUsername(member.getEmail()).password(member.getPassword())
.roles(member.getRole().name()).build();
}
}
Create MemberDetails in package service for extends UserDetails
public class MemberDetails implements UserDetails{
private Member member;
public MemberDetails(Member member){
this.member = member;
}
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return List.of(new SimpleGrantedAuthority(member.getRole().toString()));
}
public String getId(){
return member.getId();
}
@Override
public String getPassword() {
return member.getPassword();
}
@Override
public String getUsername() {
return member.getEmail();
}
}
Update MemberSerivice in package serivce change UserDetails to MemberDetails
@Service
public class MemberService implements UserDetailsService {
@Autowired
MemberRepository repository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Member member = repository.findByEmail(username);
if(member == null){
return null;
}
return new MemberDetails(member);
}
}
Create Security Config
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(request ->
request.requestMatchers("/", "/styles/*", "/auth/login", "/auth/register", "/member", "/member/**")
.permitAll()
.anyRequest().authenticated())
.formLogin(form -> form.loginPage("/auth/login")
.defaultSuccessUrl("/auth", true)
.permitAll())
.rememberMe(p -> p.key("rememberme_token").tokenValiditySeconds(60 * 60 * 24 * 30).rememberMeParameter("remember"))
.logout(p -> p.logoutUrl("/auth/logout").logoutSuccessUrl("/auth/login?logout"))
.exceptionHandling(ex -> ex.accessDeniedPage("/auth/denied"));
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
@Controller
public class AuthController {
@GetMapping("/auth")
String index(Model model, @AuthenticationPrincipal MemberDetails obj){
System.out.println(obj.getId());
model.addAttribute("obj", obj);
return "auth/index";
}
}
<ul>
<li sec:authorize="hasAuthority('Admin')"><a href="/member">Member</a></li>
<li sec:authorize="hasRole('Admin')"><a href="/member">Member2</a></li>
<li sec:authorize="isAuthenticated()"><a href="/auth" sec:authentication="name"></a></li>
<li sec:authorize="!isAuthenticated()"><a href="/auth/register">Register</a></li>
</ul>