1. 程式人生 > >Shiro整合CAS登入成功跳轉地址問題

Shiro整合CAS登入成功跳轉地址問題

最近做了ShiroCAS的整合,第一次深入Shiro,發現Shiro是一個不錯的安全框架,cas是另外一個搭建做的。

登入成功之後有3種頁面跳轉選擇,這是根據觸發登入操作的頁面分類的。
1. 當前頁面不需要登入即可訪問,點選登入按鈕,登陸成功之後留在本頁面,特別是不再首頁的情況
2. 使用者訪問的目標頁面需要登陸之後才能訪問,訪問這種頁面首先去登入頁面,登入成功再自動去目標頁面
3. 登入成功都跳轉首頁

一點警告,shiro與cas整合時shiro中配置的登入失敗的地址不應該是cas的登入地址,如果這樣配置是有問題的。

乾貨:
針對第3個:
shiro可以配置登入成功預設的跳轉地址

正對第2個:

//首先配置的shiro filter會攔截到去目標頁面的這個請求,filter如下重寫方法即可解決
/*知道一個東西,配置的shiro的filter什麼時候起作用,當用戶沒有登入的時候起作用。
如果使用者登入了shiro filter會放過請求,不對請求做任何處理
*/
@Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception{
        String loginUrl = "casServerLoginUrl?service=xxx"
; //起主要作用,儲存當前的請求資訊,登入成功之後再獲取這個請求,根據這個請求指向的頁面做跳轉 org.apache.shiro.web.util.WebUtils.saveRequest(request); //設定cas的登入地址,應該可以不用設定,因為在shiro-cas配置檔案中做了設定 org.apache.shiro.web.util.WebUtils.issueRedirect(request, response, loginUrl); return false; }

針對第1個:
採用迂迴的做法
首先在shiro配置檔案中定義一個過濾路徑 /api/shiro/login 這個路徑使用上面第2個的過濾器過濾或單獨定義(必須按照上面第2個重寫方法)

<property name="filterChainDefinitions">
    <value>
        <!-- /account/login = authc -->
        /shirocas = casFilter
        /api/shiro/login = loginFilter
    </value>
</property>
然後定義一個Controller 定義介面 /api/shiro/login
@RequestMapping(value="/api/shiro/login", method = RequestMethod.GET) 
    public Object login(HttpServletRequest request, HttpServletResponse response) {
        String redirectUrl = request.getParameter("redirect");//頁面登入按鈕設定的請求引數
        if (StringUtils.isBlank(redirectUrl)) {
            redirectUrl = request.getContextPath();
        }
        try {
            response.sendRedirect(redirectUrl);
        } catch (IOException e) {
        }
        return null;
    }
接著修改登入按鈕跳轉的地址
$("loginBtn").click(function() {window.location = '/api/shiro/login?redirect=' + window.location.href});
/*
    原理:第一 shiro 的filter先於Controller攔截請求,第二 對登入狀態下的請求shiro filter會放過,然後Controller攔截
    shiro的filter(比如loginFilter)會先於Controller攔截到請求,loginFilter儲存了當前的請求資訊(即跳轉的目標地址 /api/shiro/login),cas登入成功之後重定向到shiro的filter,shiro登入成功,然後通過org.apache.shiro.web.util.WebUtils.getAndClearSavedRequest(request)獲取上次請求的資訊,重定向到上次請求指向的路徑即:/api/shiro/login?redirect=xxx. Controller 這個時候shiro的filter攔截這個請求,一看請求已經登入,放過,Controller(見上面)攔截,然後就成功啦
*/