1.解决跨域
@Configuration
public class CorsConfig {
public CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); //允许任何域名
corsConfiguration.addAllowedHeader("*"); //允许任何头
corsConfiguration.addAllowedMethod("*"); //允许任何方法
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); //注册
return new CorsFilter(source);
}
}
2.解决sessionId不一致问题,配置shiro,重写获取sessionId方法 //自定义的 shiro session 缓存管理器,用于跨域等情况下使用 token 进行验证,不依赖于sessionId(在shiroConfig中添加) @Bean public DefaultWebSessionManager getDefaultWebSessionManager() { MySessionManager defaultWebSessionManager = new MySessionManager(); defaultWebSessionManager.setSessionDAO(new MemorySessionDAO()); return defaultWebSessionManager; } //shiro 的 session 管理(单独写一个类) //自定义session规则,实现前后分离,在跨域等情况下使用token 方式进行登录验证才需要,否则没必须使用本类。 //(shiro默认使用 ServletContainerSessionManager 来做 session 管理,它是依赖于浏览器的 cookie 来维护 session 的,调用 storeSessionId 方法保存sesionId 到 cookie中)。 //为了支持无状态会话,我们就需要继承 DefaultWebSessionManager //自定义生成sessionId 则要实现 SessionIdGenerator public class MySessionManager extends DefaultWebSessionManager { private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request"; public MySessionManager() { super(); } @Override protected Serializable getSessionId(ServletRequest request, ServletResponse response) { String id = WebUtils.toHttp(request).getHeader("Access-Token"); //如果请求头中有 token 则其值为sessionId if (!StringUtils.isEmpty(id)) { request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE); return id; } else { //否则按默认规则从cookie取sessionId return super.getSessionId(request, response); } } }
3.解决登录302问题 public class UserAuthenticationFilter extends FormAuthenticationFilter { /** * 直接过滤可以访问的请求类型 */ private static final String REQUET_TYPE = "OPTIONS"; public UserAuthenticationFilter() { super(); } @Override public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { if (((HttpServletRequest) request).getMethod().toUpperCase().equals(REQUET_TYPE)) { return true; } return super.isAccessAllowed(request, response, mappedValue); } /** * 解决302 * @param request * @param response * @throws Exception */ @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (isLoginRequest(request, response)) { if (isLoginSubmission(request, response)) { return executeLogin(request, response); } else { return true; } }else { //解决 WebUtils.toHttp 往返回response写数据跨域问题 HttpServletRequest req = WebUtils.toHttp(request); String origin = req.getHeader("Origin"); HttpServletResponse resp = WebUtils.toHttp(response); resp.setHeader("Access-Control-Allow-Origin", origin); //通过对 Credentials 参数的设置,就可以保持跨域 Ajax 时的 Cookie //设置了Allow-Credentials,Allow-Origin就不能为*,需要指明具体的url域 resp.setHeader("Access-Control-Allow-Credentials", "true"); // 返回固定的JSON串 ObjectMapper mapper = new ObjectMapper(); WebUtils.toHttp(response).setContentType("application/json; charset=utf-8"); WebUtils.toHttp(response).getWriter().print(mapper.writeValueAsString(100)); return false; } } }
4.解决权限不足302问题 public class UserAuthorizationFilter extends PermissionsAuthorizationFilter { /** * 根据请求接口路径进行验证 * @param request * @param response * @param mappedValue * @return * @throws IOException */ @Override public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException { // 获取接口请求路径 String servletPath = WebUtils.toHttp(request).getServletPath(); mappedValue = new String[]{servletPath}; return super.isAccessAllowed(request, response, mappedValue); } /** * 解决权限不足302问题 * @param request * @param response * @return * @throws IOException */ @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException { Subject subject = getSubject(request, response); if (subject.getPrincipal() != null) { return true; } else { //解决 WebUtils.toHttp 往返回response写数据跨域问题 HttpServletRequest req = (HttpServletRequest) request; String origin = req.getHeader("Origin"); HttpServletResponse resp = (HttpServletResponse) response; resp.setHeader("Access-Control-Allow-Origin", origin); //通过对 Credentials 参数的设置,就可以保持跨域 Ajax 时的 Cookie //设置了Allow-Credentials,Allow-Origin就不能为*,需要指明具体的url域 resp.setHeader("Access-Control-Allow-Credentials", "true"); WebUtils.toHttp(response).setContentType("application/json; charset=utf-8"); WebUtils.toHttp(response).getWriter().print("401"); } return false; } }
https://blog.csdn.net/China_hdy/article/details/97154272