我正在尝试使用Spring Boot和angular来更新数据,但是每当我尝试更新数据时,都会收到CORS策略阻止此错误“ http://localhost:4200”:对预检请求的响应未通过访问控制检查:所请求的资源上没有“ Access-Control-Allow-Origin”标头。
这是我的弹簧控制器和角撑杆。
我尝试了stackoverflow的其他解决方案,但不起作用 请告诉我我在做什么错..
InfoController.java
@RestController
@RequestMapping("/student")
public class InfoController {
@Autowired
private InfoDAO infoDAO;
@CrossOrigin(origins = "http://localhost:4200")
@PutMapping("/infos/{id}")
public List<Info> updateStudent(@RequestBody Info info, @PathVariable int id) {
List<Info> information = infoDAO.getbyID(id);
System.out.println("this is id");
info.setId(id);
infoDAO.update(info);
// info1.update(info1);
return information;
}
}
InfoDAO.java
List<Info> getbyID(int id);
boolean update(Info info);
InfoDAOImpl.java
public class InfoDAOImpl implements InfoDAO {
@PersistenceContext
@Autowired
private EntityManager em;
@Override
public List<Info> getbyID(int id) {
String query = "FROM Info WHERE id = :id";
return em
.createQuery(query,Info.class)
.setParameter("id",id)
.getResultList();
}
public boolean update(Info info) {
try {
em
.merge(info);
return true;
}
catch(Exception ex) {
return false;
}
}
}
SecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues())
.and().csrf().disable()
.authorizeRequests()
.antMatchers("/**").permitAll()
.antMatchers("/login").hasRole("ADMIN")
.antMatchers("/Signup").hasRole("USER")
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied")
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager(), customUserDetailService));
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowCredentials(true);
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Origin","Authorization", "Cache-Control", "Content-Type", "xsrfheadername","xsrfcookiename"
,"X-Requested-With","XSRF-TOKEN","Accept", "x-xsrf-token","withcredentials","x-csrftoken"));
configuration.setExposedHeaders(Arrays.asList("custom-header1", "custom-header2"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
Web.service.ts
export class WebService {
constructor(private httpClient: HttpClient) { }
serverUrl = 'http://localhost:8083/student';
editPlan(data: Student, id:any): Observable<any> {
const url = `/infos/${id}`;
return this.httpClient.put(this.serverUrl + url, data);
}
getWebPlanInfo(): Observable<any> {
const url = '/plan/info';
return this.httpClient.get(this.serverUrl + url);
}
}
答案 0 :(得分:2)
此问题与第cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues())
行有关。
如果删除此行,它将起作用。
但是如何?这是因为您的@Bean
方法corsConfigurationSource
将在运行时由spring容器加载,并为此创建Bean。
通过添加此行cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues())
,它会覆盖Bean corsConfigurationSource
。
applyPermitDefaultValues()
类中的此方法CorsConfiguration
将默认允许GET
,POST
,HEAD
请求方法。因此,您的PUT/DELETE
方法无法正常工作。
参考:https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java#L428
答案 1 :(得分:1)
在您的spring安全配置中,使用以下命令,以便您创建的corsconfiguration
bean被spring自动占用,而不是由http bean本身提供的配置。新的运算符,您可以自己手动创建一个实例,而不必花很多时间来自动装配下面提供的corsconfiguration
bean。因此,尝试:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/**").permitAll()
.antMatchers("/login").hasRole("ADMIN")
.antMatchers("/Signup").hasRole("USER")
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied")
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager(), customUserDetailService));
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowCredentials(true);
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
configuration.setExposedHeaders(Arrays.asList("custom-header1", "custom-header2"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
从理论上讲,如果您已进行了所有设置,Spring Security应该会在响应中自动添加诸如Access-Control-Allow-Origin
之类的响应标头。官方spring secutiy doc官方cors doc