shiro自定义登陆和推出的过滤器,实现登陆之后根据条件跳转不同页面,推出登陆根据条件跳转不同页面

shiro中我们可以通过自定义过滤器的方式来实现自己想要的结果,比如想要登陆之后跳转不同页面

@Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager,
            AuthenticationFilter authenticationFilter) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        shiroFilterFactoryBean.setSecurityManager(securityManager);

        shiroFilterFactoryBean.setSuccessUrl("/");
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/login");
        filterChainDefinitionMap.put("/login", "authc");
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/", "authc");

        Map filtersMap = new LinkedHashMap();
        filtersMap.put ("authc",new LoginFormAuthenticationFilter());//自定义登陆的过滤器
        filtersMap.put ("logout",new LogoutFormAuthenticationFilter());//自定义退出的过滤器
        shiroFilterFactoryBean.setFilters (filtersMap);

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);


        return shiroFilterFactoryBean;
    }

上面这个配置我们可以看到,将login连接配置成登陆访问的连接,但我们进行登陆提交的时候会执行authc权限的过滤器也就是这段

  filtersMap.put ("authc",new LoginFormAuthenticationFilter());//自定义登陆的过滤器

我们执行注销的时候就会执行下面这个过滤器

   filtersMap.put ("logout",new LogoutFormAuthenticationFilter());//自定义退出的过滤器

现在我们看一下两个过滤器的写法

import com.yssoft.fs.business.comm.ShiroDbRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * 说明
 *
 * @author chenyidong
 * @创建时间 2018-07-2018/7/30/030 19:50
 * @copyright © 2018
 */
public class LoginFormAuthenticationFilter extends FormAuthenticationFilter {

    private static Logger logger = LoggerFactory.getLogger(LoginFormAuthenticationFilter.class);

    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
                                     ServletResponse response) throws Exception {

        ShiroDbRealm.ShiroUser user = (ShiroDbRealm.ShiroUser) SecurityUtils.getSubject().getPrincipal();

        if(user != null) {
            HttpServletRequest req = (HttpServletRequest) request;
            String clientType = (String) req.getParameter("isPhone");

            logger.debug("[LOGIN]login success(user:" + user.loginName + ", client:" + clientType + ")");

                if("null".equals (clientType) || null==clientType) { // 正常情况下跳转的页面    
                return super.onLoginSuccess(token, subject, request, response);
            } else { // 根据类型跳转指定页面

                WebUtils.getAndClearSavedRequest(request); // 清除登录前请求路径

                req.getSession ().setAttribute ("isPhone","true");
                //其他情况自己想要跳转的页面
                String fallbackUrl = "/manager/service/list";
                WebUtils.redirectToSavedRequest(request, response, fallbackUrl);
            }
        }
        return false;
    }


}

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * 说明
 *
 * @author chenyidong
 * @创建时间 2018-07-2018/7/30/030 19:59
 * @copyright © 2018
 */
public class LogoutFormAuthenticationFilter extends LogoutFilter {
    private static Logger logger = LoggerFactory.getLogger(LogoutFormAuthenticationFilter.class);

    @Override
    protected boolean preHandle (ServletRequest request, ServletResponse response) throws Exception {
        //return super.preHandle (request, response);
        Subject subject = getSubject(request, response);
        String redirectUrl = getRedirectUrl(request, response, subject);
        HttpServletRequest req = (HttpServletRequest) request;
        String clientType =  req.getSession().getAttribute ("isPhone")+"";//在前面登陆的过滤器中存储的数据,用来分辨是不是app登陆
        subject.logout();
        logger.debug("[LOGIN]logout success( client:" + clientType + ")");
        if(!"null".equals (clientType) && null!=clientType) { // 请求方为pc,执行原方法
            issueRedirect(request, response, "/app/login");
        }else{
            issueRedirect(request, response, "/login");
        }
        return false;
    }
}

上面是登陆过滤器和注销过滤器代码,当然实现其他的功能和着两个过滤器同样配置,使用如下方式

  Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>();
        filtersMap.put ("authc",new LoginFormAuthenticationFilter());//自定义登陆的过滤器
        filtersMap.put ("logout",new LogoutFormAuthenticationFilter());//自定义退出的过滤器
        shiroFilterFactoryBean.setFilters (filtersMap);

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

你可能感兴趣的:(Shiro)