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/wmy_0707/article/details/100118329?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-3&spm=1001.2101.3001.4242
https://blog.csdn.net/China_hdy/article/details/97154272