最全的 Shiro demo Shiro 例子

JAVA herman 1389浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

关于Shiro 单点登录的功能,我后续还有案例进行教学。今天我们结合前面的一些教程,来做一个完整的Shiro 权限管理综合实例。

简单的权限管理关系图

简单的权限管理关系图

数据字典

数据库的设计,可以参考http://www.xttblog.com/?p=979。我这里主要设计用户(sys_user)、组织机构(sys_organization)、资源(sys_resource)、角色(sys_role)这几张表。具体可以按照本文末尾附件中的shiro.sql中进行创建。

  • 资源:表示菜单元素、页面按钮元素等;菜单元素用来显示界面菜单的,页面按钮是每个页面可进行的操作,如新增、修改、删除按钮;使用type来区分元素类型(如menu表示菜单,button代表按钮),priority是元素的排序,如菜单显示顺序;permission表示权限;如用户菜单使用user:*;也就是把菜单授权给用户后,用户就拥有了user:*权限;如用户新增按钮使用user:create,也就是把用户新增按钮授权给用户后,用户就拥有了user:create权限了;available表示资源是否可用,如菜单显示/不显示。
  • 角色:role表示角色标识符,如admin,用于后台判断使用;description表示角色描述,如超级管理员,用于前端显示给用户使用;resource_ids表示该角色拥有的资源列表,即该角色拥有的权限列表(显示角色),即角色是权限字符串集合;available表示角色是否可用。
  • 组织机构:name表示组织机构名称,priority是组织机构的排序,即显示顺序;available表示组织机构是否可用。
    用户:username表示用户名;password表示密码;salt表示加密密码的盐;role_ids表示用户拥有的角色列表,可以通过角色再获取其权限字符串列表;locked表示用户是否锁定。

为了简单性,如用户-角色,角色-资源关系直接在实体(用户表中的role_ids,角色表中的resource_ids)里完成的,没有建立多余的关系表,如要查询拥有admin角色的用户时,建议建立关联表,否则就没必要建立了。在存储关系时如role_ids=1,2,3,;多个之间使用逗号分隔。
 
用户组、组织机构组本实例没有实现,即可以把一组权限授权给这些组,组中的用户/组织机构就自动拥有这些角色/权限了;另外对于用户组可以实现一个默认用户组,如论坛,不管匿名/登录用户都有查看帖子的权限。

具体的表结构请查看源代码中的db/shiro-schema.sql (表结构)、db/shiro-data.sql  (初始数据)文件。默认用户名/密码是admin/123456。

实现 Realm

public class UserRealm extends AuthorizingRealm {  
    @Autowired private UserService userService;  
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
        String username = (String)principals.getPrimaryPrincipal();  
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();  
        authorizationInfo.setRoles(userService.findRoles(username));  
        authorizationInfo.setStringPermissions(userService.findPermissions(username));  
        System.out.println(userService.findPermissions(username));  
        return authorizationInfo;  
    }  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  
        String username = (String)token.getPrincipal();  
        User user = userService.findByUsername(username);  
        if(user == null) {  
            throw new UnknownAccountException();//没找到帐号  
        }  
        if(Boolean.TRUE.equals(user.getLocked())) {  
            throw new LockedAccountException(); //帐号锁定  
        }  
        return new SimpleAuthenticationInfo(  
                user.getUsername(), //用户名  
                user.getPassword(), //密码  
                ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt  
                getName()  //realm name  
        );  
    }  
}  

Web层 控制器

@Controller  
public class IndexController {  
    @Autowired  
    private ResourceService resourceService;  
    @Autowired  
    private UserService userService;  
    @RequestMapping("/")  
    public String index(@CurrentUser User loginUser, Model model) {  
        Set<String> permissions = userService.findPermissions(loginUser.getUsername());  
        List<Resource> menus = resourceService.findMenus(permissions);  
        model.addAttribute("menus", menus);  
        return "index";  
    }  
}
@Controller  
public class LoginController {  
    @RequestMapping(value = "/login")  
    public String showLoginForm(HttpServletRequest req, Model model) {  
        String exceptionClassName = (String)req.getAttribute("shiroLoginFailure");  
        String error = null;  
        if(UnknownAccountException.class.getName().equals(exceptionClassName)) {  
            error = "用户名/密码错误";  
        } else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {  
            error = "用户名/密码错误";  
        } else if(exceptionClassName != null) {  
            error = "其他错误:" + exceptionClassName;  
        }  
        model.addAttribute("error", error);  
        return "login";  
    }  
}

Web层 标签库

com.xttblog.shiro15.web.taglib.Functions提供了函数标签实现,有根据编号显示资源/角色/组织机构名称,其定义放在src/main/webapp/tld/xttblog-functions.tld。

其他的dao层,server层,配置文件等我就列举了。具体查看附件源码,导入工程即可运行。下面截取了一些运行效果。

运行效果

Shiro 整个spring 运行效果

Shiro 整个Spring 后台页面

Shiro 权限管理 项目运行效果图

附本文源代码下载链接:http://pan.baidu.com/s/1c12WPDQ 密码:vjut

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » 最全的 Shiro demo Shiro 例子