我已经配置了我的应用程序的安全性,我试图实现只有具有角色“CHEF”的用户才能在特定的post方法上添加新数据。
我设置csrf禁用,并在过滤器启用它之前。但它不起作用。
这是我的配置类:
@Configuration
@EnableMethodSecurity
public class WebSecurityConfig {
@Autowired
UserDetailsServiceCustom userDetailsService;
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(csrf -> csrf.disable())
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth.requestMatchers("/api/auth/**").permitAll()
.requestMatchers(HttpMethod.POST, "/api/receitas/add").hasAnyRole("CHEF")
.requestMatchers("/api/receitas/**").permitAll()
.anyRequest().authenticated());
http.authenticationProvider(authenticationProvider());
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class);
return http.build();
}
}
字符串
Auth入口点:
@Component
public class AuthEntryPointJwt implements AuthenticationEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException)
throws IOException, ServletException {
logger.error("Unauthorized error: {}", authException.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
}
}
型
这是我的控制器类:
@RestController
@RequestMapping("/api/receitas")
@CrossOrigin(origins = "*", maxAge = 3600)
public class ReceitaController {
@Autowired
AuthenticationManager authenticationManager;
@Autowired
private ReceitaService receitaService;
@GetMapping("/listar")
public ResponseEntity<?> listar() {
List<Receita> receitas = receitaService.findAll();
return new ResponseEntity<List<Receita>>(receitas, HttpStatus.OK);
}
@GetMapping("/chef")
@PreAuthorize("hasRole('CHEF')")
public ResponseEntity<?> teste() {
return new ResponseEntity<String>("Chef autorizado", HttpStatus.OK);
}
@PostMapping("/add")
@PreAuthorize("hasRole('CHEF')")
public ResponseEntity<?> salvar(@RequestBody CreateReceitaDTO receita) {
System.out.println("tentando fazer " + receita.getName());
try {
Receita newReceita = receitaService.createReceita(receita);
return new ResponseEntity<Receita>(newReceita, HttpStatus.CREATED);
} catch (Exception e) {
ExceptionResponse exception = new ExceptionResponse(e.getMessage(), HttpStatus.BAD_REQUEST);
return new ResponseEntity<ExceptionResponse>(exception, HttpStatus.BAD_REQUEST);
}
}
}
型
我的JWt utils类:
@Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
@Value("${teles.app.jwtSecret}")
private String jwtSecret;
@Value("${teles.app.jwtExpirationMs}")
private int jwtExpirationMs;
@Value("${teles.app.jwtCookieName}")
private String jwtCookie;
public String getJwtFromCookies(HttpServletRequest request) {
Cookie cookie = WebUtils.getCookie(request, jwtCookie);
if (cookie != null) {
return cookie.getValue();
} else {
return null;
}
}
public ResponseCookie generateJwtCookie(UserDetailsCustom userPrincipal) {
String jwt = generateTokenFromUsername(userPrincipal.getUsername());
ResponseCookie cookie = ResponseCookie.from(jwtCookie, jwt).path("/api").maxAge(24 * 60 * 60).httpOnly(true)
.build();
return cookie;
}
public ResponseCookie getCleanJwtCookie() {
ResponseCookie cookie = ResponseCookie.from(jwtCookie, null).path("/api").build();
return cookie;
}
public String getUserNameFromJwtToken(String token) {
return Jwts.parserBuilder().setSigningKey(key()).build()
.parseClaimsJws(token).getBody().getSubject();
}
private Key key() {
return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret));
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken);
return true;
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
public String generateTokenFromUsername(String username) {
try {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
.signWith(key(), SignatureAlgorithm.HS256)
.compact();
} catch (Exception e) {
throw new RuntimeException("Error while generation token", e);
}
}
}
型
当我尝试执行POST方法时,会出现以下消息:“未经授权的错误:访问此资源“”需要完全身份验证。但是当我用相同的预授权做GET时,我得到的状态是200。
1条答案
按热度按时间k0pti3hp1#
为什么你没有得到这个错误消息在GET请求到相同的请求Map是在requestMachers,你有,检查附加的截图,但对于其他端点,你没有任何角色的限制。
的数据