我正在尝试构建个人项目,但我遇到了 Spring Security 的问题,我无法回复您的帮助,我会感激不已
问题 - >问题是,即使在配置安全性和应用程序流程看起来不错之后,当我尝试使用正确的凭据保存俱乐部时,它也会给出 401 错误
我无法弄清楚问题出在哪里
这是我的安全配置类
@Configuration
@EnableMethodSecurity
public class SecurityConfig {
@Autowired
private UserDetailsServiceImpl userDetailServices;
@Autowired
private EntryPoint authEntryPoint;
@Bean
public securityFilter authFilter() {
return new securityFilter();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailServices);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration auth) throws Exception {
return auth.getAuthenticationManager();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf(csrf->csrf.disable())
.authorizeHttpRequests(auth ->
auth
.requestMatchers(
"/",
"/api/v1/auth/signin",
"/api/v1/auth/signup",
"/api/v1/auth/**",
"/v3/api-docs/**",
"/v3/api-docs.yaml",
"/swagger-ui/**",
"/swagger-ui.html").permitAll()
.requestMatchers(HttpMethod.OPTIONS,"/**").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(exception -> exception.authenticationEntryPoint(authEntryPoint))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authenticationProvider())
.addFilterBefore(authFilter(), UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
}
这是我的控制器
@PostMapping("/new")
@PreAuthorize("hasRole('MODERATOR')")
public ResponseEntity<?> saveClub(@RequestBody ClubDto clubDto) {
clubsService.saveClub(clubDto);
Map<String, String> resp = new HashMap<>();
resp.put("Message", "Club Registred Succesfully");
return ResponseEntity.ok(resp);
}
@Override
public void saveClub(ClubDto clubDto) {
Clubs clubs = new Clubs();
clubs.setTitle(clubDto.getClubName());
clubs.setContent(clubDto.getContent());
clubs.setCreatedOn(LocalDate.now());
String userContext= (String)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserEntity user =userRepository.findByUsername(userContext).
orElseThrow(()->new ResousrceNotFoundException("User not found"));
clubs.getUserEntitySet().add(user);
clubRepository.save(clubs);
}
我尝试了@Secured Annotion,它以奇怪的方式工作,它没有授权用户;没有授权发出请求的用户也在发出授权端点的请求
我尝试记录 Spring Security
Failed to authorize ReflectiveMethodInvocation: public org.springframework.http.ResponseEntity com.example.clubsapi.controller.ClubController.saveClub(com.example.clubsapi.dto.ClubDto); target is of class [com.example.clubsapi.controller.ClubController] with authorization manager org.springframework.security.config.annotation.method.configuration.DeferringObservationAuthorizationManager@1137605f and decision ExpressionAuthorizationDecision [granted=false, expressionAttribute=hasRole('MODERATOR')]
我收到了这个日志
感谢大家回复问题;我解决了。这是一个很小的错误; 我没有在 getAuthorities() 中返回权限;它被设置为 Null,这导致了
public class UserDetailsImp implements UserDetails {
private int id;
private String username;
private String password;
private Collection<? extends GrantedAuthority> authorities;
public static UserDetailsImp build(UserEntity user) {
List<GrantedAuthority> authorityList = user.getRoles().stream()
.map((role) -> new SimpleGrantedAuthority(role.getName().name()))
.collect(Collectors.toList());
return new UserDetailsImp(
user.getId(),
user.getUsername(),
user.getPassword(),
authorityList
);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}