Shiro学习总结(2)——Apache Shiro快速入门教程
第一部分 什么是Apache Shiro
1、什么是 apache shiro :
Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理
如同 spring security 一样都是是一个权限安全框架,但是与Spring Security相比,在于他使用了和比较简洁易懂的认证和授权方式。
2、Apache Shiro 的三大核心组件:
1、Subject :当前用户的操作
2、SecurityManager:用于管理所有的Subject
3、Realms:用于进行权限信息的验证
Subject:即当前用户,在权限管理的应用程序里往往需要知道谁能够操作什么,谁拥有操作该程序的权利,shiro中则需要通过Subject来提供基础的当前用户信息,Subject 不仅仅代表某个用户,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。
SecurityManager:即所有Subject的管理者,这是Shiro框架的核心组件,可以把他看做是一个Shiro框架的全局管理组件,用于调度各种Shiro框架的服务。
Realms:Realms则是用户的信息认证器和用户的权限人证器,我们需要自己来实现Realms来自定义的管理我们自己系统内部的权限规则。
3、Authentication 和 Authorization
在shiro的用户权限认证过程中其通过两个方法来实现:
1、Authentication:是验证用户身份的过程。
2、Authorization:是授权访问控制,用于对用户进行的操作进行人证授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等。
4、其他组件:
除了以上几个组件外,Shiro还有几个其他组件:
1、SessionManager :Shiro为任何应用提供了一个会话编程范式。
2、CacheManager :对Shiro的其他组件提供缓存支持。
5、Shiro 完整架构图:
图片转自:http://kdboy.iteye.com/blog/1154644
第二部分 Apache Shiro 整合Spring的Web程序构建
1、准备工具:
持久层框架:Hibernate4 这边我使用了hibernate来对数据持久层进行操作
控制显示层框架:SpringMVC 这边我使用了SpringMVC实际开发中也可以是其他框架
准备好所需要的jar放到项目中。
2、创建数据库:
首先需要四张表,分别为 user(用户)、role(角色)、permission(权限)、userRole(用户角色关系表)
这边分别创建四张表的实体类,通过Hiberante的hibernate.hbm2ddl.auto属性的update 来自动生成数据表结构。
- /***
- * 用户表
- *
- * @author Swinglife
- *
- */
- @Table(name = "t_user")
- @Entity
- public class User {
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- Integer id;
- /** 用户名 **/
- String username;
- /** 密码 **/
- String password;
- /** 是否删除 **/
- Integer isDelete;
- /** 创建时间 **/
- Date createDate;
- //多对多用户权限表
- @OneToMany(mappedBy = "user",cascade=CascadeType.ALL)
- List<UserRole> userRoles;
- 省略get set….
- }
- /****
- * 角色表
- *
- * @author Swinglife
- *
- */
- @Entity
- @Table(name = "t_role")
- public class Role {
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- Integer id;
- /**角色名**/
- String name;
- /**角色说明**/
- String description;
- }
- /****
- * 权限表
- *
- * @author Swinglife
- *
- */
- @Entity
- @Table(name = "t_permission")
- public class Permission {
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- Integer id;
- /**token**/
- String token;
- /**资源url**/
- String url;
- /**权限说明**/
- String description;
- /**所属角色编号**/
- Integer roleId;
- }
- /***
- * 用户角色表
- *
- * @author Swinglife
- *
- */
- @Entity
- @Table(name = "t_user_role")
- public class UserRole {
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- Integer id;
- @ManyToOne(cascade = CascadeType.ALL)
- @JoinColumn(name = "userId", unique = true)
- User user;
- @ManyToOne
- @JoinColumn(name = "roleId", unique = true)
- Role role;
- }
3、编写操作用户业务的Service:
- @Service
- public class AccountService {
- /****
- * 通过用户名获取用户对象
- *
- * @param username
- * @return
- */
- public User getUserByUserName(String username) {
- User user = (User) dao.findObjectByHQL("FROM User WHERE username = ?", new Object[] { username });
- return user;
- }
- /***
- * 通过用户名获取权限资源
- *
- * @param username
- * @return
- */
- public List<String> getPermissionsByUserName(String username) {
- System.out.println("调用");
- User user = getUserByUserName(username);
- if (user == null) {
- return null;
- }
- List<String> list = new ArrayList<String>();
- // System.out.println(user.getUserRoles().get(0).get);
- for (UserRole userRole : user.getUserRoles()) {
- Role role = userRole.getRole();
- List<Permission> permissions = dao.findAllByHQL("FROM Permission WHERE roleId = ?", new Object[] { role.getId() });
- for (Permission p : permissions) {
- list.add(p.getUrl());
- }
- }
- return list;
- }
- // 公共的数据库访问接口
- // 这里省略BaseDao dao的编写
- @Autowired
- private BaseDao dao;
- }
4、编写shiro组件自定义Realm:
- package org.swinglife.shiro;
- import java.util.List;
- import org.apache.shiro.authc.AuthenticationException;
- import org.apache.shiro.authc.AuthenticationInfo;
- import org.apache.shiro.authc.AuthenticationToken;
- import org.apache.shiro.authc.SimpleAuthenticationInfo;
- import org.apache.shiro.authc.UsernamePasswordToken;
- 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.swinglife.model.User;
- import org.swinglife.service.AccountService;
- /****
- * 自定义Realm
- *
- * @author Swinglife
- *
- */
- public class MyShiroRealm extends AuthorizingRealm {
- /***
- * 获取授权信息
- */
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
- //根据自己系统规则的需要编写获取授权信息,这里为了快速入门只获取了用户对应角色的资源url信息
- String username = (String) pc.fromRealm(getName()).iterator().next();
- if (username != null) {
- List<String> pers = accountService.getPermissionsByUserName(username);
- if (pers != null && !pers.isEmpty()) {
- SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
- for (String each : pers) {
- //将权限资源添加到用户信息中
- info.addStringPermission(each);
- }
- return info;
- }
- }
- return null;
- }
- /***
- * 获取认证信息
- */
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken at) throws AuthenticationException {
- UsernamePasswordToken token = (UsernamePasswordToken) at;
- // 通过表单接收的用户名
- String username = token.getUsername();
- if (username != null && !"".equals(username)) {
- User user = accountService.getUserByUserName(username);
- if (user != null) {
- return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
- }
- }
- return null;
- }
- /**用户的业务类**/
- private AccountService accountService;
- public AccountService getAccountService() {
- return accountService;
- }
- public void setAccountService(AccountService accountService) {
- this.accountService = accountService;
- }
- }
上述类继承了Shiro的AuthorizingRealm类 实现了AuthorizationInfo和AuthenticationInfo两个方法,用于获取用户权限和认证用户登录信息
5、编写LoginController:
- package org.swinglife.controller;
- import org.apache.shiro.SecurityUtils;
- import org.apache.shiro.authc.UsernamePasswordToken;
- import org.apache.shiro.subject.Subject;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.portlet.ModelAndView;
- import org.swinglife.model.User;
- import org.swinglife.service.AccountService;
- /****
- * 用户登录Controller
- *
- * @author Swinglife
- *
- */
- @Controller
- public class LoginController {
- /***
- * 跳转到登录页面
- *
- * @return
- */
- @RequestMapping(value = "toLogin")
- public String toLogin() {
- // 跳转到/page/login.jsp页面
- return "login";
- }
- /***
- * 实现用户登录
- *
- * @param username
- * @param password
- * @return
- */
- @RequestMapping(value = "login")
- public ModelAndView Login(String username, String password) {
- ModelAndView mav = new ModelAndView();
- User user = accountService.getUserByUserName(username);
- if (user == null) {
- mav.setView("toLogin");
- mav.addObject("msg", "用户不存在");
- return mav;
- }
- if (!user.getPassword().equals(password)) {
- mav.setView("toLogin");
- mav.addObject("msg", "账号密码错误");
- return mav;
- }
- SecurityUtils.getSecurityManager().logout(SecurityUtils.getSubject());
- // 登录后存放进shiro token
- UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
- Subject subject = SecurityUtils.getSubject();
- subject.login(token);
- // 登录成功后会跳转到successUrl配置的链接,不用管下面返回的链接。
- mav.setView("redirect:/home");
- return mav;
- }
- // 处理用户业务类
- @Autowired
- private AccountService accountService;
- }
6、编写信息认证成功后的跳转页面:
- package org.swinglife.controller;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- @Controller
- public class IndexController {
- @RequestMapping("home")
- public String index() {
- System.out.println("登录成功");
- return "home";
- }
- }
7、Shiro的配置文件.xml
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager" />
- <property name="loginUrl" value="/toLogin" />
- <property name="successUrl" value="/home" />
- <property name="unauthorizedUrl" value="/403" />
- <property name="filterChainDefinitions">
- <value>
- /toLogin = authc <!-- authc 表示需要认证才能访问的页面 -->
- /home = authc, perms[/home] <!-- perms 表示需要该权限才能访问的页面 -->
- </value>
- </property>
- </bean>
- <bean id="myShiroRealm" class="org.swinglife.shiro.MyShiroRealm">
- <property name="accountService" ref="accountService" />
- </bean>
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="myShiroRealm"></property>
- </bean>
- <bean id="accountService" class="org.swinglife.service.AccountService"></bean>
- <!-- <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
- <property name="cacheManager" ref="cacheManager" /> </bean> -->
loginUrl 用于配置登陆页
successUrl 用于配置登录成功后返回的页面,不过该参数只会在当登录页面中并没有任何返回页面时才会生效,否则会跳转到登录Controller中的指定页面。
unauthorizedUrl 用于配置没有权限访问页面时跳转的页面
filterChainDefinitions:apache shiro通过filterChainDefinitions参数来分配链接的过滤,资源过滤有常用的以下几个参数:
1、authc 表示需要认证的链接
2、perms[/url] 表示该链接需要拥有对应的资源/权限才能访问
3、roles[admin] 表示需要对应的角色才能访问
4、perms[admin:url] 表示需要对应角色的资源才能访问
8、登陆页login.jsp
- <body>
- <h1>user login</h1>
- <form action="login" method="post">
- username:<input type="text" name="username"><p>
- password:<input type="password" name="password">
- <p>
- ${msg }
- <input type="submit" value="submit">
- </form>
- </body>
9、运行程序
在数据库中添加一条用户、角色、以及权限数据,并且在关联表中添加一条关联数据:
在浏览器中访问: home页面 就会跳转到登录页面:
最后输入 账号密码 就会跳转到登录成功页面。
Shiro学习总结(2)——Apache Shiro快速入门教程的更多相关文章
- Apache Shiro 快速入门教程,shiro 基础教程
第一部分 什么是Apache Shiro 1.什么是 apache shiro : Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 ...
- 【shiro】shiro学习笔记1 - 初识shiro
[TOC] 认证流程 st=>start: Start e=>end: End op1=>operation: 构造SecurityManager环境 op2=>operati ...
- RabbitMQ学习总结 第二篇:快速入门HelloWorld
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- Wix学习整理(1)——快速入门HelloWorld
原文:Wix学习整理(1)--快速入门HelloWorld 1 Wix简介 Wix是Windows Installer XML的简称,其通过类XML文件格式来指定了用于创建Windows Instal ...
- springMVC学习总结(一)快速入门
springMVC学习总结(一)快速入门 一.初步认识 springMVC执行流程 主要组件 DispatcherServlet(中央控制器) 配置在web.xml中的前端控制器,客户端请求的入口,调 ...
- [shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证
本文地址:http://blog.csdn.net/sushengmiyan/article/details/39933993 shiro官网:http://shiro.apache.org/ shi ...
- Linux快速入门教程-进程管理ipcs命令学习
使用Linux系统必备的技能之一就是Linux进程管理,系统运行的过程正是无数进程在运行的过程.这些进程的运行需要占用系统的内存等资源,做好系统进程的管理,对于我们合理分配.使用系统资源有非常大的意义 ...
- Spring Boot:快速入门教程
什么是Spring Boot? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人 ...
- 专为设计师而写的GitHub快速入门教程
专为设计师而写的GitHub快速入门教程 来源: 伯乐在线 作者:Kevin Li 原文出处: Kevin Li 在互联网行业工作的想必都多多少少听说过GitHub的大名,除了是最大的开源项目 ...
随机推荐
- SSH之IDEA2017整合Struts2+Spring+Hibernate
转自:https://blog.csdn.net/sysushui/article/details/68937005
- js --- 字符串和 二进制 互相转换
//将字符串转换成二进制形式,中间用空格隔开 function strToBinary(str){ var result = []; var list = str.split("" ...
- jQuery - 设置内容和属性 设置内容 - text()、html() 以及 val() , 设置属性 - attr()
jQuery - 设置内容和属性 设置内容 - text().html() 以及 val() text() - 设置或返回所选元素的文本内容 html() - 设置或返回所选元素的内容(包括 HTM ...
- display,visibility,meta知识
<div style="display:">显示</div><div style="display:none;">隐藏不占位 ...
- 遇到的兼容性bug
1.(IE6):ie6环境下,通过设置z-index:999:无效果: 原因:IE6下,决定层级高低的不是当前的父标签,而是整个DOM tree(节点树)的第一个relative属性的父标签. 解决办 ...
- U-BOOT启动流程分析--start_armboot函数(二)
第二阶段的功能: 初始化本阶段所需的硬件设备(主要设置系统时钟.初始化串口.Flash.网卡.USB) 检测系统内存映射(memory map) 将内核映像和根文件系统映象从Flash上读到RAM空间 ...
- CodeForcesGym 100502K Train Passengers
Train Passengers Time Limit: 1000ms Memory Limit: 524288KB This problem will be judged on CodeForces ...
- Vim插件使用技巧(转)
在 IDEA Intellij小技巧和插件 一文中简单介绍了一下IdeaVim插件.在这里详细总结一下这个插件在日常编程中的一些常用小技巧.供有兴趣使用这个插件,但对Vim还不十分熟悉的朋友参考.当然 ...
- 洛谷 P1591 阶乘数码
P1591 阶乘数码 题目描述 求n!中某个数码出现的次数. 输入输出格式 输入格式: 第一行为t(≤10),表示数据组数.接下来t行,每行一个正整数n(≤1000)和数码a. 输出格式: 对于每组数 ...
- Swift之 vm10虚拟机安装Mac OS X10.10教程
VM10装Mac OS X 10.9.3及更新到Mac OS X 10.10,让你的windows也能玩Swift . 近期WWDC放出终极大招--新的编程语言Swift(雨燕),导致一大波程序猿 ...
