首页 > 代码库 > apache shiro 实战

apache shiro 实战

因为公司用到了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