问题描述
Spring Security提供的默认登录url: /login, 在前端请求访问/login时由于跨域被拦截
即
前端获取到用户名与密码向 /login 发送数据, 被拦截
问题出现的环境背景及自己尝试过哪些方法
前后端分离开发,
前端使用Vue-cli, 使用axios发送AJAX请求
后端使用SpringBoot + Spring Security
已经在Spring Security中配置了允许跨域, 自己写在Controller中的url跨域访问无任何问题, 访问Spring Security提供的/login地址被拦截
相关代码
package com.excmmy.interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class AllowCROS implements WebMvcConfigurer {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addExposedHeader("Authorization");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge(3600);
}
}
MySecurityConfig.java中代码如下
package com.excmmy.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomizeAuthenticationEntryPoint authenticationEntryPoint;
@Autowired
private CustomizeAuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private CustomizeAuthenticationFailureHandler authenticationFailureHandler;
@Autowired
private CustomizeLogoutSuccessHandler logoutSuccessHandler;
// 密码编码器
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance(); // 不使用加密算法进行密码比对
// return new BCryptPasswordEncoder(); // 使用BCrypt加密算法
}
// 安全拦截机制
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().disable();
http.csrf().disable() // 放行CSRF, 可以采用其他方式实现防止CSRF攻击
.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll() // 处理跨域请求中的Preflight请求
// 登入
.and().formLogin().
permitAll().
successHandler(authenticationSuccessHandler). // 登录成功处理逻辑
failureHandler(authenticationFailureHandler) // 登录失败处理逻辑
// 登出
.and().logout().
permitAll().
logoutSuccessHandler(logoutSuccessHandler) // 登出成功处理逻辑
// Session管理
.and().sessionManagement().
sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 对于Restful API 采用的无状态架构
// 匿名用户访问无权限资源时的异常处理
.and().exceptionHandling().
authenticationEntryPoint(authenticationEntryPoint);
}
}
你期待的结果是什么?实际看到的错误信息又是什么?
期待成功返回登录相关信息
看到的错误
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…