Читал кучу гайдов, видео, пытался разобраться так и не получилось, видимо из-за недостаточного опыта попадаешь в тупик, chatGPT не помог.
<a class="nav-link" th:href="@{/users}">List of Users</a>
Ни в какую не работает этот код:
<sec:authorize access="isAuthenticated()">
<!-- Content for Authenticated users -->
</sec:authorize>
Что бы скрыть страницу администратора /users не работает этот код
<div sec:authorize="hasRole('ADMIN')">
This content is only shown to administrators.
</div>
Перепробовал все варианты, смотрел исходники чужих проектов, результат один.
Я вижу и под юзером, и под админом, и под гостем, перепробовал множество вариантов и результат не оказывается тем, который ожидаешь, отсюда у меня появилась мысль, что проблема возможно лежит где-то в другом месте, возможно опытным путем кто-то поможет найти и решить проблемы с правами доступа?
P.S. остальные механизмы работают, например .../users/ может просматривать только админ, так и есть, обычный юзер сделать этого не может.
Вот мой код. Либо ссылка на проект https://github.com/CookieVortex/SpringBoot
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests()
.antMatchers("/", "/register").permitAll()
.antMatchers("/users", "/index").hasAnyAuthority("ADMIN")
.anyRequest().authenticated() // Require authentication for all other requests
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.usernameParameter("email")
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.deleteCookies("my-remember-me-cookie")
.permitAll()
.and()
.rememberMe()
//.key("my-secure-key")
.rememberMeCookieName("my-remember-me-cookie")
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(24 * 60 * 60)
.and()
.exceptionHandling();
}
@Controller
public class AppController {
private final UserRepository userRepo;
public AppController(UserRepository userRepo) {
this.userRepo = userRepo;
}
@GetMapping("")
public String viewHomePage(Model model) {
List<User> listUsers = userRepo.findAll();
model.addAttribute("listUsers", listUsers);
return "index";
}
@GetMapping("/register")
public String showRegistrationForm(Model model) {
model.addAttribute("user", new User());
return "signup_form";
}
@PostMapping("/process_register")
public String processRegister(User user) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodedPassword);
user.setRole("USER");
userRepo.save(user);
return "register_success";
}
@GetMapping("/users")
public String listUsers(Model model) {
List<User> listUsers = userRepo.findAll();
model.addAttribute("listUsers", listUsers);
return "users";
}
@GetMapping("/login")
public String login() {
return "login";
}
}
@Entity
@Table(schema = "dev", name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "username", nullable = false, unique = true, length = 45)
private String email;
@Column(name = "password", nullable = false, length = 64)
private String password;
@Column(name = "first_name", nullable = false, length = 20)
private String firstName;
@Column(name = "last_name", nullable = false, length = 20)
private String lastName;
@Column(name = "role", nullable = false, length = 10)
private String role;
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT u FROM User u WHERE u.email = ?1")
public User findByEmail(String email);
}
public class CustomUserDetails implements UserDetails {
private User user;
public CustomUserDetails(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singleton(new SimpleGrantedAuthority(user.getRole()));
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getEmail();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public String getFullName() {
return user.getFirstName() + " " + user.getLastName();
}
}
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepo;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepo.findByEmail(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return new CustomUserDetails(user);
}
}
<header class="header">
<ul class="nav nav-pills justify-content-end">
<li class="nav-item">
<a class="nav-link custom-style text-white bg-primary" th:href="@{/register}">Sign Up</a>
</li>
<li class="nav-item">
<a class="nav-link" th:href="@{/login}">Log In</a>
</li>
<div sec:authorize="hasRole('ADMIN')">
<li class="nav-item">
<a class="nav-link" th:href="@{/users}">List of Users</a>
</li>
</div>
</ul>
</header>