传统的登录方式都是用户名和密码组合登录,但是现在辅助登录手段多样,比如短信验证码,邮箱验证码等其他手段。这样就无法获取密码进行验证。所以本文整理了不需要密码的认证方式。
UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
Subject subject = SecurityUtils.getSubject();
Map userMap = new HashMap();
try {
//使用shiro 进行登录认证
subject.login(token);
} catch (UnknownAccountException uae) {
subject.getSession().removeAttribute(LoginString.LOGIN_KEY);
returnBean = new ReturnBean(uae, "用户名不存在");
} catch (IncorrectCredentialsException e) {
subject.getSession().removeAttribute(LoginString.LOGIN_KEY);
returnBean = new ReturnBean(e, "密码错误");
} catch (AuthenticationException e) {
// 账户认证失败
subject.getSession().removeAttribute(LoginString.LOGIN_KEY);
returnBean = new ReturnBean(e, "账户认证失败");
} catch (Exception e) {
Logger.error("登录异常{}" + ExceptionUtils.getStackTrace(e));
returnBean = new ReturnBean(e, "登录异常");
}
上述代码中我们用的认证的类是UsernamePasswordToken ,为了免密登录,需要重写UsernamePasswordToken类,如下
import org.apache.shiro.authc.UsernamePasswordToken;
public class NewUsernameToken extends UsernamePasswordToken {
private static final long serialVersionUID =1L;
private boolean type;
public NewUsernameToken() {
super();
}
public NewUsernameToken(String username, String password, boolean rememberMe, String host) {
super(username, password, rememberMe,host);
this.type = false;
}
/**免密登录*/
public NewUsernameToken(String username) {
super(username, "", false, null);
this.type = true;
}
/**账号密码登录*/
public NewUsernameToken(String username, String password) {
super(username, "", false, null);
this.type = false;
}
public boolean isType() {
return type;
}
public void setType(boolean type) {
this.type = type;
}
}
NewUsernameToken token = new NewUsernameToken(username);
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
public class MyHashedCredentialsMatcher extends HashedCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
NewUsernameToken et = (NewUsernameToken)token;
if(et.isType()){
return true;
}
Object tokenHashedCredentials = hashProvidedCredentials(token, info);
Object accountCredentials = getCredentials(info);
return equals(tokenHashedCredentials, accountCredentials);
}
}
/**
* 自定义登陆认证
* @return
*/
@Bean
public MyRealm myShiroRealm() {
MyRealm myShiroRealm = new MyRealm();
//凭证匹配
MyHashedCredentialsMatcher credentialsMatcher = new MyHashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("MD5");
credentialsMatcher.setHashIterations(2);
myShiroRealm.setCredentialsMatcher(credentialsMatcher);
return myShiroRealm;
}
//免密登录,这里传啥都无所谓
AuthenticationInfo info = new SimpleAuthenticationInfo("AA", "AA",
ByteSource.Util.bytes("AA"), getName());
上述代码是重写了AuthorizingRealm类中的doGetAuthenticationInfo方法。这样免密登录就成功了。