中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

sringboot2+shiro json接口形式未登錄時報https中有http請求錯誤

發布時間:2020-06-27 05:11:46 來源:網絡 閱讀:1163 作者:zhanfeng00 欄目:開發技術

?最近開發一個小項目采用springboot2+shiro前后端分離的方式進行。由于訪問使用https證書形式。結果在上線時遇到登錄信息過期后shiro設置的跳轉接口時重定向為http。從而https訪問http報錯。網上找了很多都沒有一個很好的解決辦法。

? ? 一開始想通過redirectHttp10Compatible:解決https環境下使用redirect重定向地址變為http的協議,無法訪問服務的問題??? ? ? ? ? ? 設置為false,即關閉了對http1.0協議的兼容支持 ,實際測試不管用。只能從shiro源碼進行分析如下:

    Java代碼 

publicboolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);
}

可以發現他是調用的isAccessAllowed方法和onAccessDenied方法,只要兩者有一個可以就可以了,從名字中我們也可以理解,他的邏輯是這樣:先調用isAccessAllowed,如果返回的是true,則直接放行執行后面的filter和servlet,如果返回的是false,則繼續執行后面的onAccessDenied方法,如果后面返回的是true則也可以有權限繼續執行后面的filter和servelt。

只有兩個函數都返回false才會阻止后面的filter和servlet的執行。

isAccessAllowed方法在這個類中都是抽象的,依靠實現類實現。onAccessDenied方法不是抽象的,但是調用了另一個抽象的方法:

org.apache.shiro.web.filter.AccessControlFilter.onAccessDenied(ServletRequest, ServletResponse)

這個方法忽略了之前配置的param參數。

這個類中還有其他的屬性,比如getLoginUrl,這個很容易猜測,是當沒有登錄的時候重定向到登錄界面的,這個方法就是獲得登錄界面的位置,默認是/login.jsp,如果我們的登錄界面不是這個的話就要重寫這個方法。

還有一個特別好使的方法

saveRequestAndRedirectToLogin(ServletRequest, ServletResponse),源碼如下:

Java代碼
protected void saveRequestAndRedirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
saveRequest(request);
redirectToLogin(request, response);
}

顯示保存了當前的request,然后重定向。

源碼如下:

Java代碼
protected void saveRequest(ServletRequest request) {
WebUtils.saveRequest(request);//關于webutils在別的博客中。
}
protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
String loginUrl = getLoginUrl();//重定向的界面就是到登錄頁面。
WebUtils.issueRedirect(request, response, loginUrl); //關于webutils在別的博客中。
}

我們如果在其他類中需要重定向的話就可以直接使用它的WebUtils.issueRedirect(request,response,loginUrl)方法了。
找到辦法了只要在onAccessDenied返回未登錄狀態就好了。

方法一:重寫FormAuthenticationFilter
原理:
假設在shiro.xml中配置了 /** = authc,而默認authc對應org.apache.shiro.web.filter.authc.FormAuthenticationFilter過濾器則表示所有路徑都被此過濾器攔截。

第一步:新建一個MyFormAuthenticationFilter類extends FormAuthenticationFilter代碼如下:

public class MyFormAuthenticationFilter extends FormAuthenticationFilter {

private static final Logger log = LoggerFactory.getLogger(MyFormAuthenticationFilter.class);

@Override
protected boolean onAccessDenied(ServletRequest request,
                                 ServletResponse response) throws IOException {

    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    Subject subject = getSubject(request, response);
    if (subject.getPrincipal() == null) {
        //設置響應頭
        httpResponse.setCharacterEncoding("UTF-8");
        httpResponse.setContentType("application/json");
        //設置返回的數據
        ResultMess resultMess = new ResultMess();
        resultMess.setCode(-10000);
        resultMess.setMsg("未登錄");
        resultMess.setSuccess(false);
        Gson gson =  new Gson();
        String result = gson.toJson(resultMess);
        //寫回給客戶端
        PrintWriter out = httpResponse.getWriter();
        out.write(result);
        //刷新和關閉輸出流
        out.flush();
        out.close();
    } else {
        //設置響應頭
        System.out.println("=========onAccessDenied==========返回json====>>>>");
        httpResponse.setCharacterEncoding("UTF-8");
        httpResponse.setContentType("application/json");
        //設置返回的數據
        ResultMess resultMess = new ResultMess();
        resultMess.setCode(-10000);
        resultMess.setMsg("未登錄");
        resultMess.setSuccess(false);
        Gson gson =  new Gson();
        String s = gson.toJson(resultMess);
        //寫回給客戶端
        PrintWriter out = httpResponse.getWriter();
        out.write(s);
        //刷新和關閉輸出流
        out.flush();
        out.close();
    }
    return false;
}

}
第二步:ShiroConfig 類中將重寫的MyFormAuthenticationFilter賦予ShiroFilterFactoryBean 代碼如下:

@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必須設置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 如果不設置默認會自動尋找Web工程根目錄下的"/login.jsp"頁面
// shiroFilterFactoryBean.setLoginUrl("/adminUser/unauth");
// 登錄成功后要跳轉的鏈接
shiroFilterFactoryBean.setSuccessUrl("/");
// 未授權界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/adminUser/unauth");
Map<String, Filter> filtersMap = new HashMap<>();
MyFormAuthenticationFilter authFilter = new MyFormAuthenticationFilter();
filtersMap.put("authc", authFilter);
shiroFilterFactoryBean.setFilters(filtersMap);

    // 配置數據庫中的resource
    Map<String, String> filterChainDefinitionMap = shiroService.loadFilterChainDefinitions();
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    return shiroFilterFactoryBean;
}

第三步:

將所以的需要攔截的標注為authc,次處的authc和filtersMap.put("authc", authFilter);設置的對應。

這樣shiro判斷到未登錄就進入次攔截器,返回json數據給前端避免了重定向url.

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巍山| 枝江市| 霸州市| 龙川县| 都江堰市| 广元市| 汨罗市| 赣榆县| 梅河口市| 格尔木市| 玉山县| 米泉市| 上犹县| 施甸县| 开封市| 六枝特区| 灌阳县| 台东市| 滁州市| 汉中市| 广西| 翁牛特旗| 富阳市| 义乌市| 右玉县| 鸡东县| 辽宁省| 明溪县| 孝义市| 长子县| 威宁| 古丈县| 浦北县| 闵行区| 大城县| 贵德县| 井冈山市| 通化市| 灵寿县| 浠水县| 土默特右旗|