shiro登录验证
身份验证
参考http://jinnianshilongnian.iteye.com/blog/2019547
步骤:
1.收集用户身份/凭证,即如用户名/密码
2.调用Subject.login()进行登录
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.AuthenticationException;
public void test(){
/*1.得到当前正在执行的主题Subject*/
Subject subject = SecurityUtils.getSubject();
/*2.创建用户名/密码身份验证Token*/
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
/*3.登录,即身份验证*/
subject.login(token);
} catch (AuthenticationException e) {
/*4.身份验证失败*/
e.printStackTrace();
System.out.println("app shiro验证失败");
}
}
会话
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.session.Session;
public sessiontest(){
/*1.得到当前正在执行的主题Subject*/
Subject curUser = SecurityUtils.getSubject();
/*2.得到主题之后,你可以得到他对应的会话信息*/
Session session = curUser.getSession();
session.setAttribute("somekey", "somevalue");// 将当前用户放入session
String value = (String) session.getAttribute("someKey");
}
加密
public SimpleHash(String algorithmName, Object source, Object salt, int hashIterations)
四个参数分别标识算法名称,散列对象,散列使用的salt值,散列次数
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
public hashtest(){
private String algorithmName = "md5";//指定hash算法为md5
private int hashIterations = 2;//指定散列次数为2次
/*1.生成盐值:取用户信息中唯一的字段来生成盐值,避免由于两个用户原始密码相同,加密后的密码也相同*/
ByteSource salt = ByteSource.Util.bytes(user.getSalt());
/*2.把密码加密,数据库密码存储时使用的加密方式要和配置文件中配置的方式相一致 :散列算法,散列次数 */
String newPassword = new SimpleHash(algorithmName, password,salt,hashIterations).toHex();
}
例子,登录验证的过程
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
private String algorithmName = "md5";//指定hash算法为md5
private int hashIterations = 2;//指定散列次数为2次
public int login(String username, String password) {
int result = 0;
if (!StringUtils.isNullorEmpty(username) && !StringUtils.isNullorEmpty(password)) {
/*1.判断该用户是否存在*/
User user = userService.findByUsername(username);
/*2.如果用户存在,去判断密码是否正确*/
if (user != null) {
ByteSource salt = ByteSource.Util.bytes(user.getSalt());//生成盐值
String newPassword = new SimpleHash(algorithmName, password,salt,hashIterations).toHex();
hashIterations).toHex(); // 把手机端传过来的密码加密
if (newPassword.equals(user.getPassword())) { // 如果密码正确,验证成功,登录
result = 1;
afterLog(user, username);
}
}
}
/*3.用户名密码和数据库匹配成功,交给shiro校验*/
if (1 == result) {
Subject subject = SecurityUtils.getSubject();//得到当前正在执行的主题Subject
UsernamePasswordToken token = new UsernamePasswordToken(username, password);//创建用户名/密码身份验证Token
try {
/*4、登录,即身份验证*/
subject.login(token);
} catch (AuthenticationException e) {
/*5、身份验证失败*/
e.printStackTrace();
System.out.println("shiro验证失败");
}
}
return result;
}
public void afterLog(User user, String username) {
Subject curUser = SecurityUtils.getSubject();//获取当前主题
Session session = curUser.getSession(); //获取当前对话
session.setAttribute("currentuser", user);// 将当前用户放入session
session.setAttribute("currentusername", username);
user.setLastLoginTime(user.getLoginTime());
user.setLoginTime(new Date());
userService.update(user);
}
生成盐值
private RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();
String salt=randomNumberGenerator.nextBytes().toHex();