【发布时间】:2020-07-19 06:15:29
【问题描述】:
我是 Spring Boot 和 Angular 的新手,正在努力解决 CORS 问题。
我想实现一个全局 CORS 过滤器并尝试实现 CorsFilter、WebMvcConfigurer 并尝试使用 WebMvcConfigurerAdapter 类,但这些方法似乎都不起作用。我知道我错过了一些东西,但不知道是什么。如果有人可以在我的代码中找到解决方案,那将是很大的帮助。
如果有帮助的话,我还实现了基本身份验证并添加了该代码。
这是我的代码。
Angular API 调用
api.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private httpClient: HttpClient) { }
userLogin(username: String, password: String) {
let postBody = {
"username" : username,
"password" : password
};
let httpOptions = {
headers : new HttpHeaders({
"Content-Type" : "application/json",
"Authorization" : "Basic " + btoa('myUsername:myPassword')
})
}
return this.httpClient.post("http://localhost:8080/userLogin", postBody, httpOptions);
}
}
这是我的 API 代码。
MainApp.java
@SpringBootApplication
public class MainApp extends SpringBootServletInitializer {
public static void main(String... str) {
SpringApplication.run(MainApp.class, str);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MainApp.class);
}
}
Config.java
@Configuration
public class Config {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
configuration.setAllowedMethods(Arrays.asList("POST"));
source.registerCorsConfiguration("/**", configuration);
return new CorsFilter(source);
}
}
NotebookController.java
@RestController
public class NotebookController {
@Autowired
IUsersRepo usersRepo;
@Autowired
INotesRepo notesRepo;
@PostMapping("userLogin")
@ResponseBody
public ResponseEntity<String> userLogin(@RequestParam("username") String username, @RequestParam("password") String password) {
ObjectWriter objectWriter = new ObjectMapper().writer().withDefaultPrettyPrinter();
List<Users> usersList = usersRepo.findByUsernameEqualsAndPasswordEquals(username, password);
boolean userVerified = usersList.size() > 0 ? true : false;
HashMap<String, Boolean> outputMap = new HashMap<>();
outputMap.put("authenticated", userVerified);
String outputJson = "";
try {
outputJson = objectWriter.writeValueAsString(outputMap);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
outputJson = outputJson.toString();
ResponseEntity<String> response = new ResponseEntity<String>(outputJson, HttpStatus.OK);
return response;
}
}
Authentication.java
@Configuration
@EnableWebSecurity
public class Authentication extends WebSecurityConfigurerAdapter {
@Autowired
AuthenticationEntryPoint authEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.cors().and().csrf().disable();
//Authorise all incoming requests
http.authorizeRequests().and().httpBasic();
http.authorizeRequests().anyRequest().authenticated();
//Use AuthenticationEntryPoint to authorise username/password
http.httpBasic().authenticationEntryPoint(authEntryPoint);
}
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
configuration.setAllowedMethods(Arrays.asList("POST"));
source.registerCorsConfiguration("/**", configuration);
return new CorsFilter(source);
}
@Bean
public BCryptPasswordEncoder getEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
String username = "myUsername";
String password = "myPassword";
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> mngConfig = authenticationManagerBuilder.inMemoryAuthentication();
mngConfig.withUser(username).password(password).roles("USER");
}
}
AuthEntryPoint.java
@Component
public class AuthEntryPoint extends BasicAuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
super.commence(request, response, authException);
response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status 401: Unauthorised | " + authException.getMessage());
}
@Override
public void afterPropertiesSet() throws Exception {
setRealmName("Online Notebook");
super.afterPropertiesSet();
}
}
请同时查看浏览器控制台。
【问题讨论】:
-
imgur.com/a/hHceJDw 的图像中显示的错误消息说,“预检响应中的访问控制允许标头不允许请求标头字段“授权”” .所以你需要改变你的代码来拥有
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"))。请不要将错误消息的屏幕截图发布到 Stack Overflow 的问题中。始终以文本形式复制并粘贴错误消息。 -
@sideshowbarker 非常感谢您的帮助。有效。我也会考虑你的建议。
标签: java angular spring spring-boot cors