1.密码的加密
在数据表中存的密码不应该是明文,而应该是明文加密之后的字符串,而且还要求这个加密算法是不可逆的,即由加密后的字符串不能反推回来原来的密码,如果能反推回来那这个加密是没有意义的。
2.MD5加密
1). 如何把一个字符串加密为MD5
2). 使用MD5加密算法后,前台用户输入的字符串如何使用MD5加密,需要做的是将当前的Realm 的credentialsMatcher属性,替换为Md5CredentialsMatcher 由于Md5CredentialsMatcher已经过期了,推荐使用HashedCredentialsMatcher 并设置加密算法即可。
shiro md5加密校验流程:
@RequestMapping("sublogin")
public String subLogin(TowattUser user){
String userName = user.getUsername();
System.out.println("当前用户:" + user.getUsername());
UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword());
Subject subject = SecurityUtils.getSubject();
token.setRememberMe(true);
try{
subject.login(token);
}catch (IncorrectCredentialsException ice){
System.out.println( "对用户【" + userName +"】进行登录验证,验证未通过,错误的凭证!");
ice.printStackTrace();
}catch (UnknownAccountException uae){
System.out.println("对用户【" + userName +"】进行登录验证,验证未通过,未知账户!");
}catch (LockedAccountException lae){
System.out.println("对用户【" + userName +"】进行登录验证,验证未通过,账户锁定!");
lae.printStackTrace();
}catch (ExcessiveAttemptsException eae){
System.out.println("对用户【" + userName +"】进行登录验证,验证未通过,错误次数太多!");
eae.printStackTrace();
}catch (AuthenticationException ae){
System.out.println("对用户【" + userName +"】进行登录验证,验证未通过,用户名、密码不正确!");
ae.printStackTrace();
}
System.out.println("登陆成功!!!");
if(subject.isAuthenticated()){
return "thymeleaf/index";
}else{
token.clear();
return "thymeleaf/sublogin";
}
}
Subject即主体,外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是一个通过浏览器请求的用户,也可能是一个运行的程序。 Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权
SecurityManager即安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。
//验证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String userName = (String)authenticationToken.getPrincipal();
TowattUser u = towattUserService.findByName(userName);
if(u == null){
throw new UnknownAccountException("没找到帐号!"); //没找到帐号
}
Object principal = u.getUsername();
Object credential = u.getPassword();
String realName = getName();
ByteSource salt = ByteSource.Util.bytes(u.getUsername()); //对用户名进行加盐
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
principal, //用户名
credential, //密码
salt, //对用户名进行加盐
realName
);
return authenticationInfo;
}
AuthenticationInfo实现Realm接口调用getAuthenticationInfo()方法进行对subject用户校验
public interface Realm {
String getName();
boolean supports(AuthenticationToken var1);
AuthenticationInfo getAuthenticationInfo(AuthenticationToken var1) throws AuthenticationException;
}
public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
AuthenticationInfo info = this.getCachedAuthenticationInfo(token);
if (info == null) {
info = this.doGetAuthenticationInfo(token);
log.debug("Looked up AuthenticationInfo [{}] from doGetAuthenticationInfo", info);
if (token != null && info != null) {
this.cacheAuthenticationInfoIfPossible(token, info);
}
} else {
log.debug("Using cached authentication info [{}] to perform credentials matching.", info);
}
if (info != null) {
this.assertCredentialsMatch(token, info);
} else {
log.debug("No AuthenticationInfo found for submitted AuthenticationToken [{}]. Returning null.", token);
}
return info;
}
protected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException {
CredentialsMatcher cm = this.getCredentialsMatcher();
if (cm != null) {
if (!cm.doCredentialsMatch(token, info)) {
String msg = "Submitted credentials for token [" + token + "] did not match the expected credentials.";
throw new IncorrectCredentialsException(msg);
}
} else {
throw new AuthenticationException("A CredentialsMatcher must be configured in order to verify credentials during authentication. If you do not wish for credentials to be examined, you can configure an " + AllowAllCredentialsMatcher.class.getName() + " instance.");
}
}
通过assertCredentialsMatch()方法进行对完成验证