標籤:style class blog code java http
因為公司用到了shiro,所以自己抽空寫了個小例子,方便下次查閱:
1.這是項目大致構架圖(至於類的實際內容會在後面有貼出):
2.資料結構說明:
User:使用者,包含 userName,password
Role:角色,包含roleName
Permission:許可權,包含premissionName
SecurityService 是資料提供者,實作類別內容如下:
package org.pan.service.impl;import org.pan.bean.Permission;import org.pan.bean.Role;import org.pan.bean.User;import org.pan.service.SecurityService;import java.util.HashSet;import java.util.Set;/** * Created by panmingzhi on 2014/6/25. */public class SecurityServiceImpl implements SecurityService { @Override public Set<Permission> findPermissionsByRoleName(String roleName) { HashSet<Permission> result = new HashSet<Permission>(); if(roleName.equals("admin")){ result.add(new Permission("carpark:*")); } if(roleName.equals("manager")){ result.add(new Permission("carpark:view")); } return result; } @Override public Set<Role> findRoleByUserName(String userName) { if(userName.equals("pan")){ HashSet<Role> roles = new HashSet<Role>(); roles.add(new Role("admin")); return roles; } if(userName.equals("fang")){ HashSet<Role> roles = new HashSet<Role>(); roles.add(new Role("manager")); return roles; } return new HashSet<Role>(); } @Override public User findUserByUserName(String username) { if(username.equals("pan")){ return new User("pan","1234"); } if(username.equals("fang")){ return new User("fang","1234"); } return null; }}
3. shiro最終許可權控制實現MyRealm.class
import org.apache.shiro.authc.*;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.pan.bean.Permission;import org.pan.bean.Role;import org.pan.bean.User;import org.pan.service.SecurityService;import org.pan.service.impl.SecurityServiceImpl;import java.util.Iterator;import java.util.Set;/** * Created by panmingzhi on 2014/6/24. */public class MyRealm extends AuthorizingRealm { private SecurityService securityService = new SecurityServiceImpl(); @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo sai = new SimpleAuthorizationInfo(); String userName = (String)principalCollection.fromRealm(getName()).iterator().next(); //尋找所擁有角色 Set<Role> roleSet = securityService.findRoleByUserName(userName); Iterator<Role> iterator = roleSet.iterator(); while(iterator.hasNext()){ Role role = iterator.next(); sai.addRole(role.getRoleName()); //尋找資源操作許可權 Set<Permission> permissionsByRoleName = securityService.findPermissionsByRoleName(role.getRoleName()); Iterator<Permission> permissionIterator = permissionsByRoleName.iterator(); while(permissionIterator.hasNext()){ sai.addStringPermission(permissionIterator.next().getPremissionName()); } } return sai; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; User user = securityService.findUserByUserName(token.getUsername()); if (user != null) { return new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), getName()); } else { return null; } }}
4.功能測試ShiroTest.class
import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.mgt.DefaultSecurityManager;import org.junit.Assert;import org.junit.BeforeClass;import org.junit.Test;/** * Created by panmingzhi on 2014/6/25. */public class ShiroTest { @BeforeClass public static void before(){ DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(new MyRealm()); SecurityUtils.setSecurityManager(defaultSecurityManager); } @Test public void loginTestSuccess(){ UsernamePasswordToken upt = new UsernamePasswordToken("pan","1234"); SecurityUtils.getSubject().login(upt); } @Test(expected = IncorrectCredentialsException.class) public void loginTestFaile(){ UsernamePasswordToken upt = new UsernamePasswordToken("pan","12345"); SecurityUtils.getSubject().login(upt); } @Test public void premissionTest(){ //管理使用者登陸 UsernamePasswordToken upt = new UsernamePasswordToken("pan","1234"); SecurityUtils.getSubject().login(upt); //斷斷是否有管理員角色 boolean admin = SecurityUtils.getSubject().hasRole("admin"); Assert.assertEquals(true,admin); //判斷是否有普通管理員角色 boolean manager = SecurityUtils.getSubject().hasRole("manager"); Assert.assertEquals(false,manager); //premission中寫道:carpark.* 代錶停車場中所有許可權 //判斷是否有停車場修改許可權 boolean permitted = SecurityUtils.getSubject().isPermitted("carpark:edit"); Assert.assertEquals(true,permitted); //判斷是否有停車場查看許可權 boolean permitted2 = SecurityUtils.getSubject().isPermitted("carpark:view"); Assert.assertEquals(true,permitted2); } @Test public void premissionTest2(){ //管理使用者登陸 UsernamePasswordToken upt = new UsernamePasswordToken("fang","1234"); SecurityUtils.getSubject().login(upt); //斷斷是否有管理員角色 boolean admin = SecurityUtils.getSubject().hasRole("admin"); Assert.assertEquals(false,admin); //判斷是否有普通管理員角色 boolean manager = SecurityUtils.getSubject().hasRole("manager"); Assert.assertEquals(true,manager); //判斷是否有停車場修改許可權 boolean permitted = SecurityUtils.getSubject().isPermitted("carpark:edit"); Assert.assertEquals(false,permitted); //判斷是否有停車場查看許可權 boolean permitted2 = SecurityUtils.getSubject().isPermitted("carpark:view"); Assert.assertEquals(true,permitted2); }}
在實際的項目中,判斷角色與許可權我一般喜歡用shiro內建的註解進行完成,這樣可以使許可權控制與業務代碼分離。
項目源碼:https://github.com/panmingzhi815/shiro.git