控制器中的特定端点给出 401 未经授权的错误,而同一控制器中的其他端点则不会给出

问题描述 投票:0回答:2
package com.hexa.amazecare.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.hexa.amazecare.dto.DoctorDTO;
import com.hexa.amazecare.service.DoctorService;

@RestController
@RequestMapping("/api/doctors")
public class DoctorController {

    @Autowired
    private DoctorService doctorService;

    // Get doctor by ID
    @GetMapping("/get/{id}")
    public ResponseEntity<DoctorDTO> getDoctorById(@PathVariable Long id) {
        DoctorDTO doctorDTO = doctorService.getDoctorById(id);
        return ResponseEntity.ok(doctorDTO);
    }
    
    //get doctors by Specialty
    @GetMapping("/get-specialty/{speciality}")
    public ResponseEntity<List<DoctorDTO>> getDoctorBySpecality(@PathVariable String specialty) {
        List<DoctorDTO> doctors = doctorService.getDoctorBySpecality(specialty);
        return ResponseEntity.ok(doctors);
    }

    // Endpoint to get all doctors
    @GetMapping("/get")
    public ResponseEntity<List<DoctorDTO>> getAllDoctors() {
        List<DoctorDTO> doctors = doctorService.getAllDoctors();
        return ResponseEntity.ok(doctors);
    }

    // Create a new doctor
    @PostMapping("/add")
    public ResponseEntity<DoctorDTO> createDoctor(@RequestBody DoctorDTO doctorDTO) {
        DoctorDTO newDoctor = doctorService.createDoctor(doctorDTO);
        return ResponseEntity.ok(newDoctor);
    }

    // Update an existing doctor
    @PutMapping("update/{id}")
    public ResponseEntity<DoctorDTO> updateDoctor(@PathVariable Long id, @RequestBody DoctorDTO doctorDTO) {
        DoctorDTO updatedDoctor = doctorService.updateDoctor(id, doctorDTO);
        return ResponseEntity.ok(updatedDoctor);
    }

    // Delete a doctor by ID
    @DeleteMapping("delete/{id}")
    public ResponseEntity<Void> deleteDoctor(@PathVariable Long id) {
        doctorService.deleteDoctor(id);
        return ResponseEntity.noContent().build();
    }
    
 // Endpoint to retrieve all specialties
    @GetMapping("/specialties")
    public ResponseEntity<List<String>> getAllSpecialties() {
        List<String> specialties = doctorService.getAllSpecialties();
        return ResponseEntity.ok(specialties);
    }
}

因此,我在医生控制器类中拥有这些端点,虽然所有端点在授权后都可以完美工作,但“getDoctorBySpecality”端点没有给出适当的结果。它给出了 401 未经授权的错误。

这是我的安全配置以供进一步了解:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    return http.csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/auth/**").permitAll() // Allow access to registration and login
                .requestMatchers("api/patients/get/**").hasAnyRole("DOCTOR","PATIENT","ADMIN")
                .requestMatchers("/api/patients/**").hasAnyRole("PATIENT","DOCTOR","ADMIN") 
                .requestMatchers("/api/doctors/get-specialty/").hasAnyRole("DOCTOR","PATIENT","ADMIN")
                .requestMatchers("/api/doctors/**").hasAnyRole("DOCTOR","PATIENT","ADMIN")
                .anyRequest().authenticated() // All other requests require authentication
            )
            .cors(Customizer.withDefaults())
            .httpBasic(Customizer.withDefaults())
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
}

你能帮我一下吗?

我尝试从邮递员访问我的端点并收到 401 未经授权的错误。我是 Spring Boot 的初学者,所以我不确定我哪里出错了。

java spring spring-boot backend react-fullstack
2个回答
1
投票

当您想要允许访问包含其他段的路由时,请始终在匹配器的末尾使用

/**
,就像您对其他端点所做的那样 例如:{id}

.requestMatchers("/api/doctors/getspecialty/**").hasAnyRole("医生","患者","管理员")

你错过了/**

还有

@GetMapping("/get-specialty/{speciality}")
        public ResponseEntity<List<DoctorDTO>> getDoctorBySpecality(@PathVariable String specialty) {
            List<DoctorDTO> doctors = doctorService.getDoctorBySpecality(specialty);
            return ResponseEntity.ok(doctors);
    }

** 你的路径中有一个拼写错误 - {speciality} 更改为 professional**


0
投票

尝试改变:

.requestMatchers("/api/doctors/get-specialty/").hasAnyRole("DOCTOR","PATIENT","ADMIN")

.requestMatchers("/api/doctors/get-specialty").hasAnyRole("DOCTOR","PATIENT","ADMIN")
© www.soinside.com 2019 - 2024. All rights reserved.