对于一般的跨域配置 只需要增添一个简单配置类
@Configuration
public class CorsConfigure {
// 有点奔放 可以更严谨点
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
config.addAllowedMethod("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
configurationSource.registerCorsConfiguration("/**", config);
return new CorsFilter(configurationSource);
}
}
服务器重定向 类似于new了一个新的请求 清除了上述配置 解决方案有两种
① 在重定向到新的请求时服务器重新添加上述配置 (感觉不好就不写了)
② 不让他重定向
1)找到重定向的代码位置
Class org.apache.shiro.web.filter.authc.FormAuthenticationFilter
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
if (this.isLoginRequest(request, response)) {
if (this.isLoginSubmission(request, response)) {
if (log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
}
return this.executeLogin(request, response);
} else {
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
return true;
}
} else {
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the Authentication url [" + this.getLoginUrl() + "]");
}
this.saveRequestAndRedirectToLogin(request, response);
return false;
}
}
2)重写未登录的重定向
public class NLFormFilter extends FormAuthenticationFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) {
Map<String,Object> result = new HashMap<>();
PrintWriter out = null;
HttpServletResponse res = (HttpServletResponse) response;
try {
res.setCharacterEncoding("UTF-8");
res.setContentType("application/json");
out = response.getWriter();
result.put("code",E.INVALID_TOKEN);
result.put("msg","登录信息过期,请重新登录");
out.println(JSONUtil.toJSONString(result));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != out) {
out.flush();
out.close();
}
}
return false;
}
@Bean
public FilterRegistrationBean registration(NLFormAuthor filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
// 具体使用在ShiroConfig中添加
registration.setEnabled(false);
return registration;
}
}
3) 在shiro配置类中添加自定义的过滤器
@Configuration
public class ShiroConfig {
/**
* TODO 缓存&配置&rememberMe 乱七八糟的就不贴了
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 设置 securityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 自定义的过滤器
Map<String, Filter> filters = new LinkedHashMap<>();
filters.put("authc",new NLFormFilter());
shiroFilterFactoryBean.setFilters(filters);
// 有序map!!!!!!!
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/login", "anon");
filterMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
}
关于OPTIONS请求
在浏览器发起非简单请求时会先发送options请求预检
上述解决方案没有对options请求进行特殊处理.也不建议加在业务服务器 可以在网关层进行处理
比如项目中运用的nginx在服务入口处检测请求类型 直接返回 减少服务器运行压力
spring cloud全家桶也有专门网关配置 可以过滤或自定义返回