自定義reaml需繼承AuthorizingRealm,並重寫doGetAuthorizationInfo(用戶獲取受權信息)和doGetAuthenticationInfo(用戶獲取認證信息)兩個方法。例如:java
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中:spring
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" ; } } }