shiro自定义过滤器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35608780/article/details/71703176
就是自定义过滤规则 一些特殊的请求路径 需要进过自定义的过滤器 在自定义的过滤器中 认证规则是自己定的

spring文件:
		<!-- 引入数据源 -->
		<context:property-placeholder location="classpath:db.properties"/>
		<!-- 配置数据库连接池 -->
		<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="maxActive" value="10" />
		<property name="maxIdle" value="5" />
		</bean>
		
		<!-- 自定义的shiro 过滤器 -->
		<bean id="phoneFilter" class="cn.neusoft.filter.UserPhoneFilter">
			<property name="userdao" ref="userDao"></property>
		</bean>	
		
		<!-- Shiro的过滤器工厂BEAN : 间接地加载9个内置过滤器  -->
		<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">		
			<!-- 安全管理器 :Shiro的核心组件,相当于大脑  -->
			<property name="securityManager" ref="securityManager" />		
			<!-- 认证相关: 指定登陆页面,当用户未登陆时访问资源,则自动跳转到此页面   -->
			<property name="loginUrl" value="/login.jsp" /> 
			<!-- 授权相关:指定错误页面,当用户登陆后访问没有权限的资源时,自动跳转到此页面 -->
			<property name="unauthorizedUrl" value="/error.html" /> 
			
			<property name="filters">
					<map>
						<entry key="phone" value-ref="phoneFilter" />
					</map>
			</property>
			
			<!-- 过滤器链定义:指定页面的访问规则 -->
			<property name="filterChainDefinitions">
				<value>	
						/userphone/login.action =anon
						/user/login.action = anon
						/login.jsp =anon
						/user/all.action = authc
						<!-- 添加的权限 -->
						/user/goadd.action =perms["add"]
						/user/add.action =perms["add"]
						<!-- 修改的权限 -->
						/user/goedit.action =perms["update"]
						/user/update.action =perms["update"]
						<!-- 删除的权限 -->
						/user/delete.action =perms["delete"]
						/userphone/* =phone
						/userphone/select.action =authc
						/userphone/add.action=perms["add"]
						/userphone/update.action =perms["update"]
						/userphone/delete.action =perms["delete"]
						/*.html = authc					
						/*.action = authc
						/* = authc
				</value>
			</property>
				
		</bean>
		<!-- 安全管理器 -->
		<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
			<property name="realm" ref="userRealm"></property>
		</bean>
		
		
		<!-- 自定义Realm -->
		<bean id="userRealm" class="cn.neusoft.realm.UserRealm">
			<property name="userService" ref="userService"></property>
			<property name="user" ref="user"></property>
		</bean>
</beans>



我们自定义了一个phoneFilter 在过滤器链中匹配到时 就会到该过滤器中执行

public class UserPhoneFilter extends AuthenticationFilter{
    
    private UserDao userdao;
    public void setUserdao(UserDao userdao) {
        this.userdao = userdao;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8"); 
        
        String sessionid = request.getParameter("sessionid");
        //1.没有sessionid    2.有sessionid  数据库没数据    3.有sessionid 数据库有数据  没有用户    4.有用户   没权限执行
        
        //判断sessionid是否存在    如不存在返回路径错误
        if(sessionid.equals("")){
            Map map = jsonReturn(false,"没有登录记录,请重新登陆");
            try {
                response.getWriter().print(JSON.toJSONString(map));
                return false;
            } catch (IOException e) {
                
                e.printStackTrace();
            }
        }
        
        PhoneId phoneId = userdao.getsession(sessionid);
        if(phoneId==null){
          //如果sessionid存在    数据库没查到    返回身份过期
            Map map = jsonReturn(false,"登录信息过期,请重新登录");
            try {
             response.getWriter().print(JSON.toJSONString(map));
             return false;
         } catch (IOException e) {
             e.printStackTrace();
         }
        }
        //数据库中根据sessionid取登陆对象
       
        
       //不为空  从数据库查到当前登陆对象
       User user = userdao.selectone(phoneId.getUid().toString());
       if(user==null){
           //通过用户ID查不到  可能已删除
           Map map = jsonReturn(false,"用户信息有问题,请重新登陆");
           try {
            response.getWriter().print(JSON.toJSONString(map));
            return false;
        } catch (IOException e) {
            e.printStackTrace();
        }
       }
       
        //------------------------------------------------------------------------------
        Subject subject = getSubject(request, response);
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword());
        subject.login(token);
        //------------------------------------------------------------------------------
        String path = getPathWithinApplication(request);
        String string = path.substring(11, path.length());
        String caozuo = string.substring(0, string.indexOf("."));
        //------------------------------------------------------------------------------
        System.out.println(caozuo);
        System.out.println("第二过滤器!!");
        //对象也从数据库查到了   出错的唯一可能就是当前对象没有权限执行
        	if(subject.isPermitted(caozuo)){
        		return true;
        	}else{
        		Map map = jsonReturn(false,"该用户没有权限执行当前资源");
        		try {
					response.getWriter().print(JSON.toJSONString(map));
				} catch (IOException e) {
				}
        		
        		return false;
        	}
	}
        
        
        

    //isAccessAllowed 方法返回false 执行
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse reponse) throws Exception {
       System.out.println("没成功!!!!!!!!!");
       return false;
    }
    
    public Map jsonReturn(boolean type,String message){
        Map map = new HashMap<Boolean, String>();
        map.put("success", type);
        map.put("value", message);
        return map;
    }
}



在自定义的过滤器中 有两个方法会先执行isAccessAllowed()方法 这个方法中如果放回false才会执行onAccessDenied() 如果放回true的话程序就会无条件执行 我们一般在isAccessAllowed()方法中执行授权
方法 subject.isPermitted(caozuo) 这个方法会执行授权方法执行成功的话放回true 执行失败的话放回false 执行onAccessDenied()方法

猜你喜欢

转载自blog.csdn.net/qq_35608780/article/details/71703176