微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从 Angular 客户端到 Spring 启动服务器的简单 POST 请求给出状态 403 错误

如何解决从 Angular 客户端到 Spring 启动服务器的简单 POST 请求给出状态 403 错误

当我尝试从 Angular 客户端向 Spring Boot 服务器执行简单的 POST 请求时,我收到此错误 403。

以下代码是 HTML 模板...

HTML 模板

<!-- Create book html -->
<div class="content-container">
  <div class="content-area">
  
    <!-- Back button -->
    <div> 
      <button class="btn btn-danger btn-block" (click)="back()">Back</button>
    </div>

    <p style="font-weight: bold; color: green;">Please enter all the details in-order to enter a new book!!!</p><br/>

    <p>{{book | json}}<p>

    <form (ngSubmit)="onCreate()">
      <!-- Book name -->
      <label for="name"><b>Book name:</b></label><br/>
      <input type="text" name="name" class="formField" size="100" placeholder="Ex: Bram Stoker's Dracula" [(ngModel)]="book.name"/><br/><br/>
    
      <!-- Author ID -->
      <label for="authorid"><b>Author ID:</b></label><br/>
      <input type="text" name="authorid" class="formField" size="50" placeholder="Ex: 100015" [(ngModel)]="book.authorID"/><br/><br/>

      <!-- Publication ID -->
      <label for="publicationid"><b>Publication ID:</b></label><br/>
      <input type="text" name="publicationid" class="formField" size="50" placeholder="Ex: 200015" [(ngModel)]="book.publicationID"/><br/><br/>
      
      <!-- Publication date -->
      <label for="publicationdate"><b>Publication Date:</b></label><br/>
      <input type="date" name="publicationdate" class="formField" [ngModel]="book.publicationDate | date:'yyyy-MM-dd'" (ngModelChange)="book.publicationDate = $event"/><br/><br/>
      
      <!-- Description -->
      <label for="description"><b>Book Description:</b></label><br/>
      <textarea name="description" class="formField" rows="3" cols="100" placeholder="Describe about the book here..." [(ngModel)]="book.description"></textarea><br/><br/>

      <!-- Edition -->
      <label for="edition"><b>Book Edition:</b></label><br/>
      <input type="text" name="edition" class="formField" size="50" placeholder="Ex: 5" [(ngModel)]="book.edition"/><br/><br/>

      <!-- Category -->
      <label for="category"><b>Book Category:</b></label><br/>
      <input type="text" name="category" class="formField" size="50" placeholder="Ex: 3" [(ngModel)]="book.category"/><br/><br/>

      <!-- rating -->
      <label for="rating"><b>Book rating:</b></label><br/>
      <input type="text" name="rating" class="formField" size="50" placeholder="Ex: 10" [(ngModel)]="book.rating"/><br/><br/>
      
      <div style="text-align:center; width:100%;">
         <button type="submit" class="btn btn-primary btn-block">Create</button>
     </div>
    </form>

  </div>
</div>

以下代码是组件...

组件

import { Component,OnInit } from '@angular/core';
import { Location } from '@angular/common';
import { Book } from '../services/data';
import { Router } from '@angular/router';
import { BookService } from '../services/book.service';

//Create book componenet 

@Component({
  selector: 'app-createbook',templateUrl: './createbook.component.html',styleUrls: ['./createbook.component.css']
})
export class CreatebookComponent implements OnInit {
  //Attributes
  book = {
    bookID: 0,name: '',authorID: 0,publicationID: 0,publicationDate: new Date,description: '',edition: 0,category: 0,rating: 0
  };

  //Constructor of the CreatebookComponent. 
  constructor(private location: Location,private router: Router,private bookService: BookService) { }

  //Component life cycle hook. Executes once componenet initiated. 
  ngOnInit(): void { }
  
  //Executes on book create. 
  onCreate() {
      this.bookService.createBook(this.book);
  }

  //Responsible for handling the back mechanism. 
  back() {
      this.location.back();
  }

}

以下代码是执行 POST 请求的服务类...

服务

import { Injectable } from '@angular/core';
import { HttpClient,HttpHeaders } from '@angular/common/http';
import { Router } from '@angular/router';
import { Book } from './data';

//Service for books in library client 

@Injectable()
export class BookService{
  //Attributes 
  recentBooks: Array<Book> = []; 
  createdBook: Book; 

  //Constructor of BookService 
  constructor(private httpClient: HttpClient,private router: Router) { }
  
  //Return the recent book array. 
  get(): Book[] {
      return this.recentBooks;
  }
  
  //Return recent books. 
  getRecentBooks() {
      return this.httpClient.get<Array<Book>>("http://localhost:8080/book/recents");//.subscribe(book => this.recentBooks=book);
      //return this.recentBooks;
  }
  
  //Responsible for creating given book. 
  createBook(theBook: any): void {
      this.httpClient.post("http://localhost:8080/book/create",theBook,{ headers: new HttpHeaders().set("Content-type","application/json") }).subscribe(result => this.redirectHome());
  }
  
  //Redirect to home page 
  redirectHome() {
      this.router.navigate(['/home']);
  }
  
}

以下代码显示了 spring boot REST 控制器代码...

REST 控制器

package com.example.LibraryServer.RestControllers;

import com.example.LibraryServer.Entities.Book;
import com.example.LibraryServer.Repositories.BookRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

/**
 * REST controller for books.
 */
@Slf4j //Lombok annotation for logger
@RestController
@RequestMapping(path = "/book",produces = "application/json")
@CrossOrigin(origins = "http://localhost:4200") //Cross-origin resource sharing
public class BookController {

    private final BookRepository bookRepo;

    /**
     * Constructor of BookController.
     * @param theBookRepository BookRepository
     */
    @Autowired
    public BookController(BookRepository theBookRepository) {
        this.bookRepo = theBookRepository;
    }

    /**
     * Responsible for returning recent books.
     * Returns maximum 12 most recently created books.
     * @return Iterable<Book>
     */
    @GetMapping("/recents")
    public Iterable<Book> recentBooks() {
        log.info("*****LibrarySystem LOGGER***** @GetMapping(/recents) -> REST endpoint executed");
        return bookRepo.recent();
    }

    /**
     * Responsible for returning the book for the given book ID.
     * @param theBookID int
     * @return ResponseEntity<Book>
     */
    @GetMapping("/{id}")
    public ResponseEntity<Book> getBook(@PathVariable("id") int theBookID) {
        log.info("*****LibrarySystem LOGGER***** @GetMapping(/{id}) -> REST endpoint executed");
        Book book = bookRepo.getByID(theBookID);
        if (book != null) {
            return new ResponseEntity<>(book,HttpStatus.OK);
        }
        else {
            return new ResponseEntity<>(null,HttpStatus.NOT_FOUND);
        }
    }

    /**
     * Responsible for deleting the book for the given book ID.
     * @param theBookID int
     */
    @DeleteMapping("/{id}")
    public void delete(@PathVariable("id") int theBookID) {
        log.info("*****LibrarySystem LOGGER***** @DeleteMapping(/{id}) -> REST endpoint executed");
        bookRepo.delete(theBookID);
    }

    /**
     * Responsible for persisting the given book.
     * @param theBook Book
     * @return Book
     */
    @PostMapping(path = "/create",consumes = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public Book save(@RequestBody Book theBook) {
        log.info("*****LibrarySystem LOGGER***** @PostMapping -> REST endpoint executed");
        return bookRepo.save(theBook);
    }

}

错误

enter image description here

Spring 启动服务器未收到请求。

请帮助我找出我的代码有什么问题,并提前感谢您在我的问题上花费的时间。

解决方法

检查安全配置我认为有问题

,

终于找到问题所在了。在我的安全配置中,我必须进行一项更改。 我确实禁用了 CSRF(跨站点请求伪造),这阻止了我的 POST 请求。

package com.example.LibraryServer.Security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

/**
 * Class responsible for security configurations.
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * Responsible for user security configuration.
     * Overridden from WebSecurityConfigurerAdapter level.
     * @param theHttpSecurity HttpSecurity
     * @throws Exception - Exception upon security configuration.
     */
    @Override
    protected void configure(HttpSecurity theHttpSecurity) throws Exception {
        theHttpSecurity.authorizeRequests()
                .antMatchers("/**").access("permitAll")
                .and().cors().and().csrf().disable();
    }

    /**
     * Responsible for configuring user-store.
     * Overridden from WebSecurityConfigurerAdapter level.
     * @param theAuthentication AuthenticationManagerBuilder
     * @throws Exception - Exception upon user store creation.
     */
    @Override
    public void configure(AuthenticationManagerBuilder theAuthentication) throws Exception {
        theAuthentication.inMemoryAuthentication()
                .withUser("sankalpa")
                .password("{noop}123")
                .authorities("ROLE_USER");
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**",configuration);
        return source;
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?