Ролевая авторизация в SecurityFilterChain не работаетJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Ролевая авторизация в SecurityFilterChain не работает

Сообщение Anonymous »

Я пытаюсь защитить конечные точки на основе ролей. Есть 3 роли: ADMIN, ESTUDIANTE (студент) и EMPRESA (компания), а у пользователя может быть только 1. Я также не храню роли в базе данных. И я пытался сделать так, чтобы только администраторы могли добавлять экземпляры CarreraEntity, но когда я пытаюсь защитить эти конечные точки в SecurityFilterChain, я получаю 403 Forbidden или могу получить доступ к этой конечной точке, несмотря на роль или даже отсутствие аутентификации.< /p>
Это мой класс SecurityConfig.

Код: Выделить всё

@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final AuthenticationProvider authProvider;
private final JwtAuthenticationFilter jwtAuthenticationFilter;

@Autowired
public SecurityConfig(AuthenticationProvider authProvider, JwtAuthenticationFilter jwtAuthenticationFilter) {
this.authProvider = authProvider;
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authRequest ->
authRequest
.requestMatchers("/api/v1/auth/**").permitAll()
.requestMatchers("/api/v1/auth/contrasenia").hasAnyRole(
Role.ADMIN.name(), Role.EMPRESA.name(), Role.ESTUDIANTE.name()
)
.requestMatchers(HttpMethod.GET, "/api/v1/carreras/**").permitAll()
.requestMatchers(HttpMethod.POST, "/api/v1/carreras/**").hasRole(Role.ADMIN.name())
.anyRequest().authenticated()
)
.sessionManagement(sessionManager ->
sessionManager
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authProvider)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
}
Вот конечные точки, которые вызывают проблемы:

Код: Выделить всё

@GetMapping
public ResponseEntity getCarreras() {
return ResponseEntity.ok(carreraService.getCarreras());
}

// TODO: return 201
@PostMapping(consumes = "application/json")
public ResponseEntity postCarrera(@RequestBody CarreraRequest request) {
return ResponseEntity.ok(carreraService.postCarrera(request));
}
Вот как я назначаю роль в утверждениях:

Код: Выделить всё

public String getToken(UserDetails user) {
HashMap claims = new HashMap();

String role = user.getAuthorities()
.stream()
.findFirst()
.map(GrantedAuthority::getAuthority)
.orElseThrow();
claims.put("role", role);

return getToken(claims, user);
}

private String getToken(HashMap map, UserDetails user) {
return Jwts.builder()
.claims(map)
.subject(user.getUsername())
.issuedAt(new Date(System.currentTimeMillis()))
.expiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24))
.signWith(this.getKey(), Jwts.SIG.HS256)
.compact();
}
А это мой класс JwtAuthenticationFilter:

Код: Выделить всё

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtService jwtService;
private final UserDetailsService userDetailsService;

@Autowired
public JwtAuthenticationFilter(JwtService jwtService, @Qualifier("userDetailsService") UserDetailsService userDetailsService) {
this.jwtService = jwtService;
this.userDetailsService = userDetailsService;
}

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
final String token = this.getTokenFromRequest(request);
final String username;

if (token == null) {
filterChain.doFilter(request, response);
return;
}

username = jwtService.getUsernameFromToken(token);

if (username != null &&  SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);

if (jwtService.isTokenValid(token, userDetails)) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);

authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

SecurityContextHolder.getContext().setAuthentication(authToken);
}
}

filterChain.doFilter(request, response);
}

private String getTokenFromRequest(HttpServletRequest request) {
final String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);

return jwtService.getTokenFromAuthorizationHeader(authHeader).orElse(null);
}
}
Вместо этого я попытался использовать MethodSecurity (@PermitAll, @PreAuthorize). Я также пытался использовать hasAuthority(). Но ни один из этих обходных путей не решил проблему. Я не знаю, что еще делать.


Подробнее здесь: https://stackoverflow.com/questions/791 ... ot-working
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»