zoukankan      html  css  js  c++  java
  • shiro拦截逻辑、springboot集成逻辑

    1.shiro拦截入口就是shiro拦截器。

    在springmvc,的时候,shiro的拦截逻辑很简单,就是在web.xml配置相应的shiro拦截器,对请求进行拦截验证是否,

    2.springboot中,其实也一样,通过配置注解@Configuration,将ShiroFilterFactoryBean和DefaultWebSecurityManager

    注入到spring容器中。其中ShiroFilterFactoryBean这个类中将

    JwtFilter添加进去,代码中粉色。DefaultWebSecurityManager,
     @Bean("shiroFilter")
        public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            // 拦截器
            Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
            if(oConvertUtils.isNotEmpty(excludeUrls)){
                String[] permissionUrl = excludeUrls.split(",");
                for(String url : permissionUrl){
                    filterChainDefinitionMap.put(url,"anon");
                }
            }
    //首页排除 filterChainDefinitionMap.put("/app/userIndex/**", "anon"); //首页接口 filterChainDefinitionMap.put("/app/notify/**", "anon"); //首页接口 filterChainDefinitionMap.put("/app/notifyAliPay/**", "anon"); //首页接口 //websocket排除 filterChainDefinitionMap.put("/websocket/**", "anon"); filterChainDefinitionMap.put("/newsWebsocket/**", "anon"); // 添加自己的过滤器并且取名为jwt Map<String, Filter> filterMap = new HashMap<String, Filter>(1); //如果cloudServer为空 则说明是单体 需要加载跨域配置 Object cloudServer = env.getProperty(CommonConstant.CLOUD_SERVER_KEY); filterMap.put("jwt", new JwtFilter(cloudServer==null)); shiroFilterFactoryBean.setFilters(filterMap); // <!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 filterChainDefinitionMap.put("/**", "jwt"); // 未授权界面返回JSON shiroFilterFactoryBean.setUnauthorizedUrl("/sys/common/403"); shiroFilterFactoryBean.setLoginUrl("/sys/common/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean("securityManager") public DefaultWebSecurityManager securityManager(ShiroRealm myRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myRealm); /* * 关闭shiro自带的session,详情见文档 * http://shiro.apache.org/session-management.html#SessionManagement- * StatelessApplications%28Sessionless%29 */ DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator(); defaultSessionStorageEvaluator.setSessionStorageEnabled(false); subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator); securityManager.setSubjectDAO(subjectDAO); //自定义缓存实现,使用redis securityManager.setCacheManager(redisCacheManager()); return securityManager; }

      

    JwtFilter类
    package org.jeecg.config.shiro.filters;
    
    import com.alibaba.fastjson.JSONObject;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
    import org.jeecg.common.constant.CommonConstant;
    import org.jeecg.config.mybatis.TenantContext;
    import org.jeecg.config.shiro.JwtToken;
    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.OutputStream;
    import java.nio.charset.StandardCharsets;
    import java.util.Date;
    
    /**
     * @Description: 鉴权登录拦截器
     * @Author: Scott
     * @Date: 2018/10/7
     **/
    @Slf4j
    public class JwtFilter extends BasicHttpAuthenticationFilter {
    
        private boolean allowOrigin = true;
    
        public JwtFilter(){}
        public JwtFilter(boolean allowOrigin){
            this.allowOrigin = allowOrigin;
        }
    
        /**
         * 执行登录认证
         *
         * @param request
         * @param response
         * @param mappedValue
         * @return
         */
        @Override
        protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
            try {
                executeLogin(request, response);
                return true;
            } catch (Exception e) {
                throw new AuthenticationException("Token失效,请重新登录", e);
            }
        }
    
        /**
         *
         */
        @Override
        protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            String token = httpServletRequest.getHeader(CommonConstant.X_ACCESS_TOKEN);
    
            JwtToken jwtToken = new JwtToken(token);
            // 提交给realm进行登入,如果错误他会抛出异常并被捕获
            getSubject(request, response).login(jwtToken);
            // 如果没有抛出异常则代表登入成功,返回true
            return true;
        }
    
        /**
         * 对跨域提供支持
         */
        @Override
        protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            if(allowOrigin){
                httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
                httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
                httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
                //update-begin-author:scott date:20200907 for:issues/I1TAAP 前后端分离,shiro过滤器配置引起的跨域问题
                // 是否允许发送Cookie,默认Cookie不包括在CORS请求之中。设为true时,表示服务器允许Cookie包含在请求中。
                httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
                //update-end-author:scott date:20200907 for:issues/I1TAAP 前后端分离,shiro过滤器配置引起的跨域问题
            }
            // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
            if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
                httpServletResponse.setStatus(HttpStatus.OK.value());
                return false;
            }
            //update-begin-author:taoyan date:20200708 for:多租户用到
            String tenant_id = httpServletRequest.getHeader(CommonConstant.TENANT_ID);
            TenantContext.setTenant(tenant_id);
            //update-end-author:taoyan date:20200708 for:多租户用到
            try{
                return super.preHandle(request, response);
            }catch (Exception e){
                httpServletResponse.setStatus(HttpStatus.OK.value());
                JSONObject data = new JSONObject();
                data.put("code", 403);
                data.put("message", "Token失效,请重新登录");
                data.put("success", false);
                data.put("now", new Date().getTime());
                /**获取OutputStream输出流*/
                OutputStream outputStream = response.getOutputStream();
                /**设置json返回格式*/
                ((HttpServletResponse) response).setHeader("content-type", "application/json");
                /**将字符转换成字节数组,指定以UTF-8编码进行转换*/
                byte[] dataByteArr = data.toJSONString().getBytes(StandardCharsets.UTF_8);
                /**使用OutputStream流向客户端输出字节数组*/
                outputStream.write(dataByteArr);
                return false;
            }
    
            //return super.preHandle(request, response);
        }
    }
    

      

  • 相关阅读:
    RabbitMQ In JAVA 介绍及使用
    JSON Web Token 入门教程
    char* 与 char[] 的区别
    C++ namespace的用法
    启动其他APK的Activity方法 (转至http://www.cnblogs.com/lijunamneg/archive/2013/02/26/2934060.html)
    Android多任务切换与Activity启动模式SingleTask之间关系的分析
    对SingleTask和TaskAffinity的理解(转至 http://www.2cto.com/kf/201311/254450.html)
    正在运行的android程序,按home键之后退回到桌面,在次点击程序图标避免再次重新启动程序解决办法
    大牛的博客
    Androidpn 简单实现及分析
  • 原文地址:https://www.cnblogs.com/longsanshi/p/14284763.html
Copyright © 2011-2022 走看看