1、自定義Realm
public class UserRealm extends AuthorizingRealm {
private StuServiceImpl stuService = new StuServiceImpl();
private RoleServiceImpl roleService = new RoleServiceImpl();
private PermissionServiceImpl permissionService = new PermissionServiceImpl();
@Override
public String getName() {
return this.getClass().getName().toString();
}
/**
* 認證,該方法只在認證的時候執行一次
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("doGetAuthenticationInfo");
String name = (String) authenticationToken.getPrincipal();
Stu stu = stuService.getStuByName(name);
// 密碼到後期在判斷,涉及加密相關
if(stu != null){
List<String> roles = roleService.getRoleByName(name);
List<String> permissions = permissionService.getPermissionByName(name);
ActiveStu activeStu = new ActiveStu(stu,roles,permissions);
// 構造方法第一個參數:任意對象
// 構造方法第二個參數:通常爲密碼
// 構造方法第三個參數:通常爲當前類名
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(activeStu,stu.getPwd(),this.getName());
return info;
}
return null;
}
/**
* 授權,注意-->該方法會在每次進行授權操作的時候都執行一次
* 不能每次都去數據庫查一次,解決方法有:
* 1、使用緩存,然後用aop切進來,判斷是否有緩存
* 2、在認證成功後將權限傳遞過來
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("doGetAuthorizationInfo");
// getPrimaryPrincipal 就是獲取在doGetAuthenticationInfo返回對象中的第一個構造方法參數
ActiveStu activeStu = (ActiveStu) principalCollection.getPrimaryPrincipal();
// SimpleAuthorizationInfo是AuthorizationInfo的子類
SimpleAuthorizationInfo info = info = new SimpleAuthorizationInfo();
// 判斷是否爲超級管理員
if(activeStu.getStu().getType() == 0){
info.addStringPermission("*:*");
info.addRole("*:*");
}else{
List<String> roles = activeStu.getRoles();
List<String> permissions = activeStu.getPermissions();
if(null != roles && roles.size() > 0){
info.addRoles(roles);
}
if(null != permissions && permissions.size() > 0){
info.addStringPermissions(permissions);
}
}
return info;
}
2、測試類
public class TestMyRealm {
public static void main(String[] args) {
// new一個Factory工廠
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 得到SecurityManager或其子類對象
DefaultSecurityManager securityManager = (DefaultSecurityManager) factory.getInstance();
// 設置自定義的Realm,設置後將不會讀取ini文件的內容
UserRealm realm = new UserRealm();
securityManager.setRealm(realm);
// 設置到當前線程
SecurityUtils.setSecurityManager(securityManager);
// 得到subject對象
Subject subject = SecurityUtils.getSubject();
// 進行認證操作
String name = "zs";
String pwd = "123456";
try{
UsernamePasswordToken token = new UsernamePasswordToken(name,pwd);
subject.login(token);
System.out.println(name + " 是否登錄成功:"+subject.isAuthenticated());
}catch (AuthenticationException e){
System.out.println("賬號或密碼錯誤!");
}
// 授權判斷
boolean role1 = subject.hasRole("*:*");
System.out.println(name + " 是否具有 *:* 角色:"+role1);
boolean permitted = subject.isPermitted("*:*");
System.out.println(name + " 是否具有 *:* 權限:"+permitted);
}
}
結果
3、實體類
// 學生實體類
public class Stu {
private String name;
private String pwd;
// 0:超級管理員,1:普通用戶
private int type;
public Stu(String name, String pwd,int type) {
this.name = name;
this.pwd = pwd;
this.type=type;
}
// get...set...
}
// 角色、權限、用戶對象
public class ActiveStu {
private Stu stu;
private List<String> roles;
private List<String> permissions;
public ActiveStu(Stu stu, List<String> roles, List<String> permissions) {
this.stu = stu;
this.roles = roles;
this.permissions = permissions;
}
// get...set...
}
4、服務類
public class StuServiceImpl implements StuMapper {
public Stu getStuByName(String name) {
Stu stu = null;
// 模擬從數據庫查詢數據
if("zs".equals(name)){
stu = new Stu("zs","123456",0);
}else if("ls".equals(name)){
stu = new Stu("ls","123456",1);
}
return stu;
}
}
public class RoleServiceImpl implements RoleMapper {
public List<String> getRoleByName(String name) {
// 模擬從數據庫查詢數據
if("zs".equals(name)){
return Arrays.asList(new String[]{"role1","role2","role3"});
}else if("ls".equals(name)){
return Arrays.asList(new String[]{"role1"});
}
return null;
}
}
public class PermissionServiceImpl implements PermissionMapper {
public List<String> getPermissionByName(String name) {
// 模擬從數據庫查詢數據
if("zs".equals(name)){
return Arrays.asList(new String[]{"user:c","user:r","user:u","user:q"});
}else if("ls".equals(name)){
return Arrays.asList(new String[]{"user:c"});
}
return null;
}
}