持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情
3、项目骨架
4、ShiroDbRealm定义
【1】简介
【2】原理分析
(1)、ShiroDbRealmImpl继承ShiroDbRealm向上继承AuthorizingRealm,ShiroDbRealmImpl实例化时会创建密码匹配器HashedCredentialsMatcher实例,HashedCredentialsMatcher指定hash次数与方式,交于AuthenticatingRealm
(2)、调用login方法后,最终调用doGetAuthenticationInfo(AuthenticationToken authcToken)方法,拿到SimpleToken的对象,调用UserBridgeService的查找用户方法,把ShiroUser对象、密码和salt交于SimpleAuthenticationInfo去认证
(3)、访问需要鉴权时,调用doGetAuthorizationInfo(PrincipalCollection principals)方法,然后调用UserBridgeService的授权验证
【3】核心类代码
【3.1】ShiroDbRealm
package com.itheima.shiro.core;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import javax.annotation.PostConstruct;
/**
*
* @Description shiro自定义realm
*/
public abstract class ShiroDbRealm extends AuthorizingRealm {
/**
* @Description 认证
* @param authcToken token对象
* @return
*/
public abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) ;
/**
* @Description 鉴权
* @param principals 令牌
* @return
*/
public abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals);
/**
* @Description 密码匹配器
*/
@PostConstruct
public abstract void initCredentialsMatcher() ;
}
【3.2】ShiroDbRealmImpl
package com.itheima.shiro.core.impl;
import com.itheima.shiro.constant.SuperConstant;
import com.itheima.shiro.core.base.ShiroUser;
import com.itheima.shiro.core.base.SimpleToken;
import com.itheima.shiro.core.ShiroDbRealm;
import com.itheima.shiro.core.bridge.UserBridgeService;
import com.itheima.shiro.pojo.User;
import com.itheima.shiro.utils.BeanConv;
import com.itheima.shiro.utils.DigestsUtil;
import com.itheima.shiro.utils.EmptyUtil;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Description:自定义shiro的实现
*/
public class ShiroDbRealmImpl extends ShiroDbRealm {
@Autowired
private UserBridgeService userBridgeService;
/**
* @Description 认证方法
* @param authcToken 校验传入令牌
* @return AuthenticationInfo
*/
@Override
public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
SimpleToken token = (SimpleToken)authcToken;
User user = userBridgeService.findUserByLoginName(token.getUsername());
if(EmptyUtil.isNullOrEmpty(user)){
throw new UnknownAccountException("账号不存在");
}
ShiroUser shiroUser = BeanConv.toBean(user, ShiroUser.class);
shiroUser.setResourceIds(userBridgeService.findResourcesIdsList(user.getId()));
String salt = user.getSalt();
String password = user.getPassWord();
return new SimpleAuthenticationInfo(shiroUser, password, ByteSource.Util.bytes(salt), getName());
}
/**
* @Description 授权方法
* @param principals SimpleAuthenticationInfo对象第一个参数
* @return
*/
@Override
public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
return userBridgeService.getAuthorizationInfo(shiroUser);
}
/**
* @Description 加密方式
*/
@Override
public void initCredentialsMatcher() {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(SuperConstant.HASH_ALGORITHM);
matcher.setHashIterations(SuperConstant.HASH_INTERATIONS);
setCredentialsMatcher(matcher);
}
}
【3.3】SimpleToken
package com.itheima.shiro.core.base;
import org.apache.shiro.authc.UsernamePasswordToken;
/**
-
@Description 自定义tooken */ public class SimpleToken extends UsernamePasswordToken {
/** serialVersionUID */ private static final long serialVersionUID = -4849823851197352099L;
private String tokenType;
private String quickPassword;
/**
- Constructor for SimpleToken
- @param tokenType */ public SimpleToken(String tokenType, String username,String password) { super(username,password); this.tokenType = tokenType; }
public SimpleToken(String tokenType, String username,String password,String quickPassword) { super(username,password); this.tokenType = tokenType; this.quickPassword = quickPassword; }
public String getTokenType() { return tokenType; }
public void setTokenType(String tokenType) { this.tokenType = tokenType; }
public String getQuickPassword() { return quickPassword; }
public void setQuickPassword(String quickPassword) { this.quickPassword = quickPassword; }
}