前端提供两种方式
代码:
普通登录就直接进行登录,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端也登录不上