防止 shiro 认证失败后跳转页面,自定义shiro授权过滤器

    技术2023-09-02  80

    防止 shiro 认证失败后跳转页面,自定义shiro授权过滤器

    一、注册自定义授权过滤器一、创建自定义授权过滤器

    一、注册自定义授权过滤器

    import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.Cookie; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.crazycake.shiro.RedisCacheManager; import org.crazycake.shiro.RedisManager; import org.crazycake.shiro.RedisSessionDAO; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import quantity.knowledgebase.realm.CustomSessionManager; import quantity.knowledgebase.realm.MyFormAuthenticationFilter; import quantity.knowledgebase.realm.MyRealm; import javax.servlet.Filter; import java.util.LinkedHashMap; import java.util.concurrent.ConcurrentHashMap; /** * shiro配置类 */ @Configuration public class ShiroFilterConf { /** * ShrioFilterFactoryBean 过滤bena * * @param defaultWebSecurityManager * @return */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); /*********************************主要内容***************************/ /***************************注册自定义授权过滤器**********************/ // 1、创建过滤器Map,用来装自定义过滤器 LinkedHashMap<String, Filter> linkedHashMap = new LinkedHashMap<>(); // 2、将自定义过滤器放入map中,如果实现了自定义授权过滤器,那就必须在这里注册,否则Shiro不会使用自定义的授权过滤器 linkedHashMap.put("authc", new MyFormAuthenticationFilter()); // 3、将过滤器Ma绑定到shiroFilterFactoryBean上 bean.setFilters(linkedHashMap); /**********************************************************************/ //设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); /* 添加shiro的内置过滤器 anon 无需认证就可以访问 authc 必须认证才能访问 user 必须拥有记住我功能 才能用 perms 拥有对某个用户资源才能访问 role 拥有某个角色权限才能访问 */ ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>(); //FormAuthenticationFilter authc 认证过滤器 //AnonymousFilter anon 匿名过滤器 map.put("/personnel_gm/**", "authc"); map.put("/product/**", "authc"); map.put("/statistics_offer/**", "authc"); //定义一个过滤器链 bean.setFilterChainDefinitionMap(map); //其他资源都需要认证 authc 表示需要认证才能进行访问 user表示配置记住我或认证通过可以访问的地址 return bean; } /** * 安全对象 FafaulWebSecurityManager * * @param userRealm * @return */ @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") MyRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //关联UserRealm securityManager.setRealm(userRealm); securityManager.setSessionManager(sessionManager()); // 安全管理器中 设置 sessionManager securityManager.setCacheManager(cacheManager()); return securityManager; } /** * 创建 Realm对象 ,需要自定义Realm * * @return */ @Bean public MyRealm userRealm() { MyRealm userRealm = new MyRealm(); return userRealm; } /** * 会话管理器 * * @return */ @Bean public DefaultWebSessionManager sessionManager() { CustomSessionManager sessionManager = new CustomSessionManager(); sessionManager.setSessionDAO(redisSessionDAO()); Cookie sessionIdCookie = sessionManager.getSessionIdCookie(); sessionIdCookie.setPath("/"); sessionManager.setSessionIdCookie(sessionIdCookie); return sessionManager; } /** * 配置redisManager * * @return */ public RedisManager getRedisManager() { RedisManager redisManager = new RedisManager(); redisManager.setHost("192.168.0.1:6379"); redisManager.setPassword("123456"); return redisManager; } /** * 配置具体cache实现类 * * @return */ public RedisCacheManager cacheManager() { RedisCacheManager redisCacheManager = new RedisCacheManager(); redisCacheManager.setRedisManager(getRedisManager()); //设置redis过期时间,单位是秒 redisCacheManager.setExpire(60*60*24*360*5); redisCacheManager.setKeyPrefix("ihrm:shiro:cache:"); //设置权限信息缓存的名称前缀 return redisCacheManager; } /** * 自定义session持久化 * * @return */ public RedisSessionDAO redisSessionDAO() { RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); redisSessionDAO.setRedisManager(getRedisManager()); redisSessionDAO.setExpire(60*60*24*360*5); redisSessionDAO.setKeyPrefix("ihrm:shiro:session:"); //设置session缓存的名称前缀 return redisSessionDAO; } /** * 管理shiro一些bean的生命周期 即bean初始化 与销毁 * * @return */ @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * 加入注解的使用,不加入这个AOP注解不生效(shiro的注解 例如 @RequiresGuest , 但是 一般使用配置文件的方式) * * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager); return authorizationAttributeSourceAdvisor; } /** * 用来扫描上下文寻找所有的Advistor(通知器), 将符合条件的Advisor应用到切入点的Bean中,需 * 要在LifecycleBeanPostProcessor创建后才可以创建 * * @return */ @Bean @DependsOn("lifecycleBeanPostProcessor") public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setUsePrefix(true); return defaultAdvisorAutoProxyCreator; } }

    一、创建自定义授权过滤器

    import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import org.json.JSONObject; import quantity.knowledgebase.util.HttpGetIpUtil; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; public class MyFormAuthenticationFilter extends FormAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { System.out.println("验证失败"); HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.setStatus(200); httpServletResponse.setContentType("application/json;charset=utf-8"); PrintWriter out = httpServletResponse.getWriter(); JSONObject json = new JSONObject(); json.put("code", -1); json.put("msg", "登录已失效,请重新登录!"); out.println(json); out.flush(); out.close(); return false; } }
    Processed: 0.010, SQL: 9