因为公司用到了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
apache shiro 实战,布布扣,bubuko.com
原文:http://www.cnblogs.com/panmingzhi815/p/3807259.html