为了解决Spring Boot + Spring Security无法实现跨域问题,我们可以采取以下步骤:
1. 添加依赖
首先,在pom.xml
中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.11.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.11.3</version>
</dependency>
其中,Spring Boot相关依赖的版本可以根据需求进行更改。
2. 配置CORS
接下来,在SpringBootSecurity
中添加CorsConfigurationSource
配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// ...省略其他配置
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOriginPattern("*");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
这里的配置允许所有来源的请求,并且允许任何请求头和方法,开启允许携带Cookie。如果需要更加细致的CORS控制,可以自行配置。
3. 添加全局异常处理器
为了方便统一处理异常信息,我们可以添加全局异常处理器。这里我们使用Spring的@ControllerAdvice
和@ExceptionHandler
注解来实现。
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseResult<Void> handle(Exception e) {
// 自定义ResponseResult类,用来包装API统一响应格式
ResponseResult<Void> result = new ResponseResult<>();
if (e instanceof AccessDeniedException) {
result.setCode(403);
result.setMessage("访问被拒绝");
} else {
result.setCode(500);
result.setMessage("服务器内部错误");
}
return result;
}
}
示例1
假设我们有一个UserController
用来处理用户账号的相关操作,这里我们需要支持从不同域名的前端项目中发送请求。我们可以在该类上添加@CrossOrigin
注解来解决跨域问题。
@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})
public class UserController {
// ...
}
示例2
这里我们尝试通过XML格式来发送POST请求,以application/xml
为Content-Type。首先,我们需要定义一个自定义的XML消息转换器:
@Configuration
public class XmlHttpMessageConverterConfig {
@Bean
public HttpMessageConverter<Object> xmlHttpMessageConverter() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
ObjectMapper mapper = builder.createXmlMapper(true).build();
return new MappingJackson2HttpMessageConverter(mapper);
}
}
然后,我们来为User
类添加XML支持:
@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
// ...
}
最后,我们构造一个XML格式的请求体,并发送请求:
String requestBody = "<user><name>Tom</name><age>28</age><email>tom@example.com</email><password>123456</password></user>";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
HttpEntity<String> request = new HttpEntity<>(requestBody, headers);
User result = restTemplate.exchange(url, HttpMethod.POST, request, User.class).getBody();
至此,我们完成了Spring Boot + Spring Security的跨域问题解决,并且支持了XML格式的请求和响应。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot+Spring Security无法实现跨域的解决方案 - Python技术站