Shiro 多登录地址

1.需求

原先的user表数据。相当于多个部门, 每个部门都有自己登录地址,其实用的功能都一样。 不想多布置服务器,但登录地址又不一样。找了网上不少内容参考终于搞出来了。

2. 登录代码修改

用户类型枚举类

loginTypeEnums

重写 UsernamePasswordToken

public class UserPasswordToken extends UsernamePasswordToken {

    private static final long serialVersionUID = -1L;

    private String loginType;

    public UserPasswordToken(String username, char[] password,String loginType) {
        super(username, password);
        this.loginType = loginType;
    }

    public String getLoginType() {
        return loginType;
    }

    public void setLoginType(String loginType) {
        this.loginType = loginType;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

}

根据loginType 写对应的realm

Xxxx extends AuthorizingRealm 基本一样就名字不一样 ModularRealmAuthenticator中需要根据loginTpe 判断realm

重写ModularRealmAuthenticator, 根据提交的loginType选择realm

public class ModelRealmAuthenticator extends ModularRealmAuthenticator {
    @Override
    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        assertRealmsConfigured();
        UserPasswordToken customizedToken = (UserPasswordToken) authenticationToken;
        String loginType = customizedToken.getLoginType();
        Collection<Realm> realms = getRealms();
        Collection<Realm> loginRealms = new ArrayList<>();
        AuthenticationException authenticationException = null;
        for (Realm realm : realms) {

            if (realm.getName().contains(loginType)) {
                 AuthenticationInfo info = null;
                try {
                    info = realm.getAuthenticationInfo(authenticationToken);
                } catch (AuthenticationException e) {
                //为了抓自定义的AccountException
                    authenticationException = e;
                }
                loginRealms.add(realm);
            }
        }

        if(authenticationException != null){
            throw authenticationException;
        }

        if (loginRealms.size() == 1)
            return doSingleRealmAuthentication(loginRealms.iterator().next(), customizedToken);
        else
            return doMultiRealmAuthentication(loginRealms, customizedToken);
    }
}

根据loginType的类型写重写对应的FormAuthenticationFilter 登录操作

public class UserFormAuthenticationFilter extends FormAuthenticationFilter {

    public static final String LOGIN_TYPE = loginTypeEnums.WEB.getType();

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        if(request.getAttribute(getFailureKeyAttribute()) != null) {
            return true;
        }
        return super.onAccessDenied(request, response, mappedValue);
    }

    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
                                     ServletResponse response) throws Exception {
        WebUtils.getAndClearSavedRequest(request);
        WebUtils.redirectToSavedRequest(request, response, "/");// 页面跳转到首页
        return false;
    }
    @Override
    protected UserPasswordToken createToken(ServletRequest request, ServletResponse response) {
        String username = getUsername(request);
        String password = getPassword(request);

         return new UserPasswordToken(username, password.toCharArray(), LOGIN_TYPE);
    }
	@Override
    protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
        String loginUrl = "/user/login";
        WebUtils.issueRedirect(request, response, loginUrl);
    }
}

3. 登出代码

public class MyLogoutFilter extends LogoutFilter {
    private static final Logger log = LoggerFactory.getLogger(LogoutFilter.class);

    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        Subject subject = getSubject(request, response);
        Session session = subject.getSession();
        User user = (User) session.getAttribute(Constants.CURRENT_USER);
        
        if (user != null) {
  			//realm登录的时候把userType放入session中了
            String userType = (String) session.getAttribute(user.getUsername());
            if (LoginType.JISHU.getType().equals(userType)) {
                this.setRedirectUrl("/jishu/login");
            } if (StringUtils.isEmpty(userType)) {
                this.setRedirectUrl(this.DEFAULT_REDIRECT_URL);
            }
        }
        String redirectUrl = getRedirectUrl(request, response, subject);
    
        try {
            subject.logout();
        } catch (SessionException ise) {
            log.debug("Encountered session exception during logout.  This can generally safely be ignored.", ise);
        }
        //设置登出后的跳转地址
        issueRedirect(request, response, redirectUrl);
        return false;
    }

}

4. 超时时跳转处理

用的cookie 携带 loginType .

  1. 不同登录login操作时设置cookie中的logintType
  2. 重写AccessControlFilter的onAccessDenied(ServletRequest request, ServletResponse response) 方法判断未登录时cookie里loginType的类型来设置this.setLoginUrl(xxx)返回不同的登录地址.

5. 配置spring-shiro.xml

配置多个realm ,DefaultWebSecurityManager 中realms. 重写的filter ,ShiroFilterFactoryBean 引入重写的filter

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值