I try to get User Id, but have exception -> java.lang.NullPointerException: No authorized user found. Have custom AuthUser:
import lombok.Getter;
import lombok.Setter;
import org.springframework.lang.NonNull;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import ru.lozovoi.service.domain.User;
import java.util.Collections;
import static java.util.Objects.requireNonNull;
public class AuthUser extends org.springframework.security.core.userdetails.User {
@Getter
@Setter
@NonNull
private User user;
public AuthUser(@NonNull User user) {
super(user.getUsername(), user.getPassword(), Collections.singletonList(new SimpleGrantedAuthority(user.getRole())));
this.user = user;
}
public static AuthUser safeGet() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null) {
return null;
}
Object principal = auth.getPrincipal();
return (principal instanceof AuthUser au) ? au : null;
}
public static AuthUser get() {
return requireNonNull(safeGet(), "No authorized user found");
}
public static User authUser() {
return get().getUser();
}
public static long authId() {
return get().id();
}
public long id() {
return user.getId();
}
}
My entity:
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.List;
@Data
@Entity
@Table(name = "users")
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String email;
private Date registered;
private String role;
// @JoinColumn
// @ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
// @CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
// @Enumerated(EnumType.STRING)
// private Set<Role> roles;
@OneToMany
@JoinColumn(name = "user_id")
private List<Car> cars;
}
Controller method:
@PostMapping(value = "/record")
public String create(@Valid Record record, BindingResult result, Model model) {
// if (result.hasErrors()) {
// return "record-form";
// }
User user = AuthUser.get().getUser();
Long id = user.getId();
recordRepository.save(record, id);
return "redirect:/cars";
}
Configured UserDetails:
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import ru.lozovoi.service.domain.User;
import java.util.Collection;
import java.util.Collections;
@Data
public class UserDetailsImpl implements UserDetails {
User user;
public UserDetailsImpl(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singletonList(new SimpleGrantedAuthority(user.getRole()));
}
@Override
public String getPassword() {
return this.user.getPassword();
}
@Override
public String getUsername() {
return this.user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public String toString() {
return "UserDetailsImpl{" +
"user=" + user +
'}';
}
}
And securityConfig:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.web.SecurityFilterChain;
import ru.lozovoi.service.service.UserService;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final UserService userService;
@Autowired
public SecurityConfig(UserService userService) {
this.userService = userService;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable().
authorizeHttpRequests(auth -> auth.requestMatchers("/auth/login", "/auth/registration", "/error", "/")
.permitAll()
.requestMatchers("/users").hasRole("ADMIN")
.anyRequest()
.permitAll()//must be authenticated
)
.formLogin()
.loginPage("/auth/login")
.loginProcessingUrl("/process_login")
.defaultSuccessUrl("/", true)
.failureForwardUrl("/auth/login?error")
.and();
return http.build();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
auth.setUserDetailsService(userService);
auth.setPasswordEncoder(passwordEncoder());
return auth;
}
}
I try get user with Authentication, Principal and SecurityContextHolder.getContext().getAuthentication(). All variables doesn't work.