Cas统一身份认证与db认证

前端提供两种方式

代码:



普通登录就直接进行登录,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认证)