当前位置: 首页 > 知识库问答 >
问题:

实现Spring Security性后,删除和放置终结点不起作用

奚英朗
2023-03-14

我目前正在开发一个带有React前端和Spring Boot后端的fullstack web应用程序。我已经为身份验证实现了Spring Security性和JWT,但此后我无法访问APIendpoint(请参阅控制器)。我已经设法访问了GET请求endpoint,但是,尽管在启动请求之前登录了后端,但PUT或DELETE请求似乎都不起作用。

我在另一篇文章中看到禁用csrf解决了这个问题,但我从来没有启用过它,所以这对我来说不起作用。

WebSecurity配置文件:

@Configuration
@AllArgsConstructor
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                    .antMatchers("/api/v*/registration/**")
                    .permitAll()
                .anyRequest()
                .authenticated().and()
                .formLogin();
    }

控制器(REST API)

@RestController
@RequestMapping(path = "/question")
@CrossOrigin("*")
public class QuestionController {

    private final QuestionService questionService;

    @Autowired
    public QuestionController(QuestionService questionService) {
        this.questionService = questionService;
    }

    @CrossOrigin("*")
    @GetMapping("/all")
    public ResponseEntity<List<Question>> getAllQuestions() {
        List<Question> questions = questionService.findAllQuestions();
        return new ResponseEntity<>(questions, HttpStatus.OK);
    }

    @CrossOrigin("*")
    @GetMapping("/find/{id}")
    public ResponseEntity<Question> getQuestionById(@PathVariable("id") Long id) {
        Question question = questionService.findQuestionById(id);
        return new ResponseEntity<>(question, HttpStatus.OK);
    }

    @CrossOrigin("*")
    @PostMapping("/add")
    public ResponseEntity<Question> addQuestion(@RequestBody Question question) {
        Question newQuestion = questionService.addQuestion(question);
        return new ResponseEntity<>(newQuestion, HttpStatus.CREATED);
    }

    @CrossOrigin("*")
    @PutMapping("/update/{id}")
    public ResponseEntity<Question> updateQuestion(@RequestBody Question question) {
        Question updateQuestion = questionService.updateQuestion(question);
        return new ResponseEntity<>(updateQuestion, HttpStatus.OK);
    }

    @CrossOrigin("*")
    @DeleteMapping("(/delete/{id}")
    public ResponseEntity<Question> deleteQuestion(@PathVariable("id") Long id) {
        questionService.deleteQuestion(id);
        return new ResponseEntity<>(HttpStatus.OK);
    }
}

编辑:这是实现UserDetailsService的代码

@Service
@Autowired can be left out by using this annotation.
@AllArgsConstructor
public class BenutzerkontoService implements UserDetailsService {

    private final static String USER_NOT_FOUND_MSG = "User with email %s not found";

    private final BenutzerkontoRepository benutzerkontoRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;
    private final ConfirmationTokenService confirmationTokenService;

    public List<Benutzerkonto> findAllBenutzerkonto() {
        // findAll() returns a list of all user objects
        return benutzerkontoRepository.findAll();
    }

    /**
     * This method is responsible for identifying the given email inside the database.
     *
     * @param email
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        return benutzerkontoRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException(String.format(USER_NOT_FOUND_MSG, email)));
    }

    /**
     * The following function checks, whether the user already exists (by email) and registers the user with an
     * encoded password, if the email address does not exist already.
     *
     * The user also gets a random JSON Web Token assigned
     *
     * @param benutzerkonto
     * @return
     */
    public String signUpUser(Benutzerkonto benutzerkonto) {
        // Check whether user exists
        boolean userExists = benutzerkontoRepository.findByEmail(benutzerkonto.getEmail()).isPresent();

        if (userExists) {
            throw new IllegalStateException("Email is already taken");
        }

        // Encode the user password
        String encodedPassword = bCryptPasswordEncoder.encode(benutzerkonto.getPassword());

        // Replace the plain text password with the encoded version
        benutzerkonto.setPasswort(encodedPassword);

        // Save user to database
        benutzerkontoRepository.save(benutzerkonto);

        // Create random String via the UUID class for using it as token
        String token = UUID.randomUUID().toString();

        // Instantiate ConfirmationToken class, which defines the token for account confirmation
        ConfirmationToken confirmationToken = new ConfirmationToken(
                token,
                LocalDateTime.now(),
                // Make token invalid after 15 minutes
                LocalDateTime.now().plusMinutes(15),
                benutzerkonto
        );

        // Save token to database
        // TODO: Shouldn't it be saved by a confirmationTokenRepository object? Why does this also work?
        confirmationTokenService.saveConfirmationToken(confirmationToken);

        return token;
    }

    /**
     * This function takes the email address as a parameter and enables/activates the email for logging in.
     *
     * @param email
     * @return
     */
    public int enableAppUser(String email) {
        return benutzerkontoRepository.enableAppUser(email);
    }

    /**
     * This method adds a new user account to the database, but it searches for the passed value of email
     * inside the database first. The user object "benutzerkonto" will only be saved in the database repository,
     * if the email does not exist already.
     *
     * @param benutzerkonto
    */
    public void addNewUser(Benutzerkonto benutzerkonto) {
        // userEmailPresence can be null, if the email does not exist in the database yet, which is why it's an Optional.
        Optional<Benutzerkonto> userEmailPresence = benutzerkontoRepository.findBenutzerkontoByEmail(benutzerkonto.getUsername());
        if (userEmailPresence.isPresent()) {
            throw new IllegalStateException("Email already taken.");
        } else {
            benutzerkontoRepository.save(benutzerkonto);
        }

    }

}

共有1个答案

鲜于子琪
2023-03-14

因此,除了请求 /api/v*/注册/**其他都是安全的。这是什么意思?,这意味着在您拥有授权角色的授权用户之前,无法访问任何其他终结点。所以你需要做一些事情,比如:

>

  • 实现包组织的UserDetails。springframework。安全果心userdetails并实现该方法:

    @覆盖公共收藏

    向实体类添加角色:

    @OneTo很多(读取=FetchType.EAGER,级联=CascadeType。PERSIST)@JoinTable(name="user_role",joinColns=@JoinColiv(name="user_id",引用的列名="id"),inverseJoinColns=@JoinColiv(name="role_id",引用的列名="id"))私有列表角色;

    在endpoint中使用这些角色:

    @preAuthorize(hasRole('ROLE_role_name'))@GetMap(path=EndPoint.PATIENT_HOME,消耗="应用程序/json",产生="应用程序/json")公共响应实体主页(主要主体){

     return new ResponseEntity<YourDTO>(yourDTO, HttpStatus.OK);
    

    }

  •  类似资料:
    • 我尝试使用Registfit2.0来实现一个库系统。可以添加图书,列出所有图书信息,列出一本书信息,删除一本书,删除所有图书,更新一本书信息。 我的baseURL结尾有一个“/”: 前三个特性工作得很好: 您将在响应中看到,检查请求信息,method是“get”,但标记显示method=“delete”。 Update2:根据Dexter的建议,我添加了用于调试的HttpLoggingInterc

    • 问题内容: 我有以下通常正常工作的代码: 对于我的许多实体类来说,这都是可行的。但是对于其中的两个它什么也不做,它不会引发任何异常,也不会删除该对象。来自hibernate的日志显示,hibernate执行了许多选择查询,但它甚至没有尝试执行删除。 我已经在这里和这里尝试了在其他类似问题中发现的建议,但是没有用(嗯,后者建议我不能使用,但是我只是在和之间加上了语句)。 我似乎找不到这两个类比其他类

    • 我有以下通常运行良好的代码: 对于我的许多实体类,这很有效。但是,对于其中两个,它什么都不做,它不会引发任何异常,也不会删除对象。来自Hibernate的日志显示Hibernate执行了许多选择查询,但它甚至不会尝试执行删除。 我已经尝试了在这里和这里的其他类似问题中找到的建议,但无济于事(好吧,后者建议我不能使用,但我只是将语句括在和之间)。 我似乎找不到这两个班比其他班多(或少)什么。他们使用

    • 我一直在阅读一篇又一篇的帖子和文章,试图让级联删除在最新的Spring Boot版本中与JPA/Hibernate配合使用。我读过你必须使用Hibernate特定的级联,我读过你不需要。我读过它们就是不起作用,但它似乎是一个混合体。我尝试过的一切都不起作用。这种关系是双向的。 不工作: 不工作: 在删除品牌之前,除了删除税率之外,还有什么其他方法有效吗? 我的测试如下所示: 参考错误: 原因:or

    • 问题内容: 我试图通过执行以下循环来获取TreeMap的前10个元素: 该打印 工具,为什么可能不起作用? 更新 这是我的实现: 更新 这很有用:Java Map按值排序。 问题答案: public int compare(Integer a, Integer b) { if (base.get(a) >= base.get(b)) { return -1; } else { return 1;

    • 我使用的是Kafka版本0.8.2。在开发过程中,我想我可能需要删除一个主题。所以我所做的是在服务器配置文件中放入以下一行,并启动两台kafka服务器。 当我需要删除一个主题并运行以下命令时, 现在距我运行“删除主题”命令已经17个小时了,但Kafka仍在向我显示该主题已标记为删除。是Kafka的虫子还是我在这里做错了什么?因为在我看来这不正常。有人能就此澄清一下吗?