Springboot整合shiro安全框架,前後端分離的常見問題

1.shiro攔截註解無反應

//權限註解
@RequiresPermissions()
//角色權限註解
@RequiresRoles()

2.連接成功之後,需要在cookie中有getsessionId,前後端分離需要,繼承DefaultWebSessionManager重寫getSessionId方法,並且需要注入到Bean中

package xxx.xxx.xxx.xxx;

import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;

/**
 * Description:shiro框架 自定義session獲取方式
 * 可自定義session獲取規則。這裏採用ajax請求頭Authorization攜帶sessionId的方式
 **/
public class MySessionManager extends DefaultWebSessionManager {

    private static final String AUTHORIZATION = "Authorization";

    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(AUTHORIZATION);
        System.out.println("id:"+id);
        if(StringUtils.isEmpty(id)){
            //如果沒有攜帶id參數則按照父類的方式在cookie進行獲取
            System.out.println("super:"+super.getSessionId(request, response));
            return super.getSessionId(request, response);
        }else{
            //如果請求頭中有 authToken 則其值爲sessionId
            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;
        }
    }
}

需要 sessionManager注入到bean中,並且關聯到securityManager中進行處理

    @Bean
    public SessionManager sessionManager(){
     return new MySessionManager();
    }



    @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("MyRealm")MyRealm myRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //關聯realm
        securityManager.setRealm(myRealm);
        //關聯securityManager
        securityManager.setSessionManager(sessionManager());
        return securityManager;
    }

3.添加攔截返回信息過濾器(前後端分離如果問題,需要自定義攔截返回類型是什麼結果集)

package xxx.xxx.xxx.xxx;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.json.JSONObject;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * 配置shiro自定義攔截響應類
 */
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setContentType("application/json; charset=utf-8");
        PrintWriter out = httpServletResponse.getWriter();
        JSONObject json = new JSONObject();
        json.put("status","401");
        json.put("msg","非法訪問,沒有請求頭的Token令牌!");
        out.println(json);
        out.flush();
        out.close();
        return false;
    }
}

將過濾攔截信息類放入ShiroFilterFactoryBean中,進行處理也就是我們的shiroconfig.java類

 map.put("user", new MyFormAuthenticationFilter());

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章