美文网首页
Cas统一身份认证与db认证

Cas统一身份认证与db认证

作者: wilesan | 来源:发表于2021-05-26 17:16 被阅读0次

    前端提供两种方式

    代码:

    <button  class="btn btn-success btn-block" onclick="checkLogin();">统一认证登录</button>
    <button class="btn btn-success btn-block" id="btnSubmit" data-loading="正在验证登录,请稍后...">登&emsp;录</button>
    

    普通登录就直接进行登录,cas登录则进入统一的登录页面,如下:

    function checkLogin(){
        window.open('https://ids6.****.***.cn/authserver/login?service=https%3A%2F%2F***.****.****.com%2Fdemo%2Fcas%2Flogin','_self');
    }
    

    与shiro权限整合

    主要思想是通过cas认证的用户直接再用shiro免密登录一下

    1.ShiroConfig中开放cas路径

    filterChainDefinitionMap.put("/cas/**", "anon");
    

    2.加登录类型class

    public enum LoginType {
        PASSWORD("password"), // 密码登录
        NOPASSWD("nopassword"); // 免密登录
        private String code;// 状态值
    
        private LoginType(String code) {
            this.code = code;
        }
    
        public String getCode() {
            return code;
        }
    }
    

    3.重写UsernamePasswordToken,主要是加了一个登录类型

    public class CustomToken extends UsernamePasswordToken {
        private static final long serialVersionUID = -2564928913725078138L;
        private LoginType type;
        public CustomToken() {
            super();
        }
    
        public CustomToken(String username, String password, LoginType type, boolean rememberMe, String host) {
            super(username, password, rememberMe, host);
            this.type = type;
        }
    
        /**
         * 免密登录
         */
        public CustomToken(String username) {
            super(username, "", false, null);
            this.type = LoginType.NOPASSWD;
        }
    
        /**
         * 账号密码登录
         */
        public CustomToken(String username, String password) {
            super(username, password, false, null);
            this.type = LoginType.PASSWORD;
        }
    
        public LoginType getType() {
            return type;
        }
    
    
        public void setType(LoginType type) {
            this.type = type;
        }
    }
    

    4.修改UserRealm中的登录认证方法,区别正常登录和免密登录
    UserRealm.java中

    @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
        {
            //UsernamePasswordToken upToken = (UsernamePasswordToken) token;
            CustomToken upToken = (CustomToken) token;
            String username = upToken.getUsername();
            String password = "";
            if (upToken.getPassword() != null)
            {
                password = new String(upToken.getPassword());
            }
    
            SysUser user = null;
            try
            {
                if(upToken.getType()== LoginType.PASSWORD) {
                    user = loginService.login(username, password);
                }else{
                    user = loginService.noPassLogin(username);
                }
            }
          ............
    

    5.添加 noPassLogin方法和noPassValidate方法

    public SysUser noPassLogin(String username)
        {
    
            // 查询用户信息
            SysUser user = userService.selectUserByLoginName(username);
            if (user == null)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
                throw new UserNotExistsException();
            }
            if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete")));
                throw new UserDeleteException();
            }
            if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
                throw new UserBlockedException();
            }
            passwordService.noPassValidate(user);
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
            recordLoginInfo(user);
            return user;
        }
    
    public void noPassValidate(SysUser user)
        {
            String loginName = user.getLoginName();
            clearLoginRecordCache(loginName);
        }
    

    6.修改认证成功后的contorller

     //UsernamePasswordToken token = new UsernamePasswordToken(uid, "password");
    CustomToken customToken = new CustomToken(uid);
    customToken.setType(LoginType.NOPASSWD);
    subject.login(customToken);
    return redirect("/index");
    

    7.正常通过db登录的controller

    //UsernamePasswordToken token = new UsernamePasswordToken(uid, "password");
    CustomToken token = new CustomToken(username, RsaUtils.decryptByPrivateKey(password));
    token.setType(LoginType.PASSWORD);
    Subject subject = SecurityUtils.getSubject();
    subject.login(token);
    return success();
    

    8.cas注销
    系统中本地服务器注销后还需要注销cas登录状态

    @Override
    protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject)
     {
            String casLogoutURL = "https://ids6.****.****.cn/authserver/logout";
            String redirectURL = casLogoutURL + "?service=https%3A%2F%2F****.****.***.com%2F****";
            return  redirectURL;
     }
    

    存在的问题

    1.如果别的cas client注销后,本系统还是可以正常运行,因为本地登录的记录没有变化
    2.如果本系统中注销,则本系统和cas服务器端都会注销,别的cas client端也登录不上

    相关文章

      网友评论

          本文标题:Cas统一身份认证与db认证

          本文链接:https://www.haomeiwen.com/subject/rxnksltx.html