自定义reaml需继承AuthorizingRealm,并重写doGetAuthorizationInfo(用户获取授权信息)和doGetAuthenticationInfo(用户获取认证信息)两个方法。例如:
import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import javax.annotation.Resource; import org.apache.log4j.Logger; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.SimplePrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; public class MyRealm extends AuthorizingRealm { /** * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用. */ private static Logger logger = Logger.getLogger(MyRealm.class); //不要引入业务逻辑层service @Autowired private UserDao userDao; @Autowired private RoleDao roleDao; public MyRealm(){ super(); } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { // TODO Auto-generated method stub logger.debug("do get user authorizationInfo"); String loginName = (String) arg0.fromRealm(getName()).iterator().next(); logger.debug("get loginName is :"+loginName); User user = userDao.getUser(loginName); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); if(object instanceof Users){ //获取用户的permission信息 Set<String> permissions = roleUserDao.getUserAllPermissions(user.getUser_id()); logger.debug("get all user permissions from db "+permissions); if(permissions.size()==0){//不具备系统操作权限 logger.debug("login user role is normal"); info.addRole("normal"); }else{ info.addRole("admin"); info.setStringPermissions(permissions); } } return info; } /** * 认证回调函数,登录时调用. */ @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken arg0) throws AuthenticationException { logger.debug("do Get user authenticationInfo"); UsernamePasswordToken token = (UsernamePasswordToken) arg0; try { User user = userDao.getUser(token.getUsername()); logger.debug("get user infos :"+object); Users user = (Users)object; if(user.getForbidden_status().equals(R.USERTYPE_INACTIVE)){ throw new AuthenticationException("用户处于禁用状态"); }else{ return new SimpleAuthenticationInfo(user.getUser_uid(), user.getUser_pwd(), getName()); } }catch(Exception e){ logger.error(e.getMessage(),e); } return null; } }
对应的logginController中:
public class myController { @RequestMapping("/gotoLogin.do") public String gotoLogin(@ModelAttribute UserBean userBean,Model model,HttpSession session){
//获取subject对象
Subject subject = SecurityUtils.getSubject();
//根据用户的输入的用户名和密码创建token对象 UsernamePasswordToken token = new UsernamePasswordToken(userBean.getUserId(),userBean.getPassword()); try {
//调用login方法,此时对根据doGetAuthenticationInfo方法返回的SimpleAuthenticationInfo对象进行对比,如果密码不正确或用户名不存在将抛出对应的异常信息 subject.login(token); session.setAttribute("USER", userBean);return "/test/main" ; }catch (Exception e){ model.addAttribute("error","用户名或密码错误") ; return "login" ; } }
}