5.13.1 需求
修改realm的doGetAuthenticationInfo,从数据库查询用户信息,realm返回的用户信息中包括 (md5加密后的串和salt),实现让shiro进行散列串的校验。
1.1.1 修改doGetAuthenticationInfo从数据库查询用户信息
1、将SysService注入到realm中。

//realm的认证方法,从数据库查询用户信息
@Override
**protected** AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) **throws** AuthenticationException {
// token是用户输入的用户名和密码
// 第一步从token中取出用户名
String userCode = (String) token.getPrincipal();
// 第二步:根据用户输入的userCode从数据库查询
SysUser sysUser = **null**;
**try** {
sysUser = sysService.findSysUserByUserCode(userCode);
} **catch** (Exception e1) {
// **TODO** Auto-generated catch block
e1.printStackTrace();
}
// 如果查询不到返回null
**if**(sysUser==**null**){//
**return** **null**;
}
// 从数据库查询到密码
String password = sysUser.getPassword();
//盐
String salt = sysUser.getSalt();
// 如果查询到返回认证信息AuthenticationInfo
//activeUser就是用户身份信息
ActiveUser activeUser = **new** ActiveUser();
activeUser.setUserid(sysUser.getId());
activeUser.setUsercode(sysUser.getUsercode());
activeUser.setUsername(sysUser.getUsername());
//..
//根据用户id取出菜单
List<SysPermission> menus = **null**;
**try** {
//通过service取出菜单
menus = sysService.findMenuListByUserId(sysUser.getId());
} **catch** (Exception e) {
// **TODO** Auto-generated catch block
e.printStackTrace();
}
//将用户菜单 设置到activeUser
activeUser.setMenus(menus);
//将activeUser设置simpleAuthenticationInfo
SimpleAuthenticationInfo simpleAuthenticationInfo = **new** SimpleAuthenticationInfo(
activeUser, password,ByteSource.Util.*bytes*(salt), **this**.getName());
**return** simpleAuthenticationInfo;
}
设置 凭证匹配器,设置密码的散列次数,也可以自定义
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 添加文件配置路径 cacheManager 设置输入密码不能超过5次 -->
<!-- <constructor-arg ref="cacheManager" /> -->
<!-- 加密方式 -->
<property name="hashAlgorithmName" value="md5" />
<!-- 加密次数 -->
<!-- 定义密码加密算法及迭代次数 -->
<property name="hashIterations" value="1" /><!--1次md5迭代-->
<!-- 存储散列后的密码是否为16进制 -->
<property name="storedCredentialsHexEncoded" value="true" />
</bean>
自定义
<!-- 凭证匹配器 -->
<bean id="credentialsMatcher"
class="com.neusoft.saca.datacatalog.shrio.DataCatalogCredentialsMatcher">
<constructor-arg ref="cacheManager" />
<property name="hashAlgorithmName" value="md5" />
<property name="hashIterations" value="2" />
<property name="storedCredentialsHexEncoded" value="true" />
</bean>
DataCatalogCredentialsMatcher
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
public class DataCatalogCredentialsMatcher extends HashedCredentialsMatcher {
private Cache<String, AtomicInteger> passwordRetryCache;
public DataCatalogCredentialsMatcher(CacheManager cacheManager) {
passwordRetryCache = cacheManager.getCache("passwordRetryCache");
}
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
String username = (String) token.getPrincipal();
AtomicInteger retryCount = passwordRetryCache.get(username);
if (retryCount == null) {
retryCount = new AtomicInteger();
passwordRetryCache.put(username, retryCount);
}
if (retryCount.incrementAndGet() > 5) {
throw new ExcessiveAttemptsException();
}
boolean matchs = super.doCredentialsMatch(token, info);
if (matchs) {
passwordRetryCache.remove(username);
}
return matchs;
}
public Cache<String, AtomicInteger> getPasswordRetryCache() {
return passwordRetryCache;
}
public void setPasswordRetryCache(Cache<String, AtomicInteger> passwordRetryCache) {
this.passwordRetryCache = passwordRetryCache;
}
网友评论