shiro权限框架
权限的组成部分:用户 资源 角色 权限
数据库关系表设计是根据自己项目需求设计的
account表
role表(id,rolename)
account_role(id,aid,rid)
permission(id,pername)
role_permission(id,rid,pid)
没有设置用户和权限的关系,我们可以认为用户的权限是通过角色来决定的
1.导入jar包
shiro-all-1.2.1.jar
2.配置web.xml
<!-- 权限过滤器-->
<filter>
<filter-name>shiroFilter</filter-name>
<!-- 委托给spring,所以还要在spring中配置 -->
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.新建applicationContext-shiro.xml
因为在web.xml中有配置spring容器,它会读取applicationContext开头的配置文件
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<!-- 权限框架的操作类 myShiroRealm,可以service中新建这个类-->
<property name="realm" ref="myShiroRealm"/>
</bean> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/> <!-- 以下是跟登录权限有关的配置 --> <!-- 配置登录的url -->
<property name="loginUrl" value="/"/>
<!-- 登录成功的url -->
<property name="successUrl" value="/book/1"/>
<!-- 没有权限的url -->
<property name="unauthorizedUrl" value="/403"/> <property name="filterChainDefinitions">
<value> <!-- 静态资源不用认证 要放在/** = authc之前,因为当所有的都要认证的时候再写它就没用了-->
/static/** = anon
<!-- 角色配置,没有管理员这个角色的账户是不能访问/book/**里面的内容的 -->
/book/** = roles[管理员]
<!-- 权限配置,不要只在界面上用标签配置 没有book:add的权限的账户是不能访问/book/add的
但是如果没有权限你还是要访问的话,就要到上面的<property name="unauthorizedUrl" value="/403"/>
里面了,自定义一个403页面,这里举出一个例子,可以在mvc-servlet配置静态资源
<mvc:view-controller path="/403" view-name="403"/>-->
/book/add = perms[book:add] <!-- (根目录及其子目录)所有的资源都是需要认证的 这个时候以前mvc-servlet里面的拦截器就不用写了-->
/** = authc
</value>
</property>
</bean> <bean id="cacheManager"
class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
<bean id="lifecycleBeanPostProcessor"
class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> </beans>
举例
package com.kaishengit.service; import javax.inject.Inject;
import javax.inject.Named; 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 com.kaishengit.pojo.Admin; // 需要继承自AuthorizingRealm并实现它的方法
@Named
public class MyShiroRealm extends AuthorizingRealm{ @Inject
private AdminService adminService; /**
* 权限认证方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pCollection) {
//获取当前登录的用户名
String loginName = (String) pCollection.fromRealm(getName()).iterator().next(); Admin admin = adminService.findByName(loginName);
if(admin != null) {
SimpleAuthorizationInfo sInfo = new SimpleAuthorizationInfo();
//1. 获取当前用户拥有的所有角色
sInfo.setRoles(adminService.getRoles(admin));
/* adminService中的该方法
public Set<String> getRoles(Admin admin) {
List<Role> roles = roleDao.findByAdminId(admin.getId());
因为是要返回的set集合
Set<String> roleNames = new HashSet<String>(); for(Role r : roles) {
roleNames.add(r.getRolename());
}
return roleNames;
}*/ //2. 获取当前用户拥有的所有权限
// 还有一个方法,跟下面的不同的是set第二次会覆盖,add表示添加
//sInfo.addStringPermissions(adminService.getPermissions(admin));
sInfo.setStringPermissions(adminService.getPermissions(admin)); /* adminService中的该方法
public Set<String> getPermissions(Admin admin) {
一个账户可能有多个角色
List<Role> roles = roleDao.findByAdminId(admin.getId()); Set<String> permissions = new HashSet<String>(); for(Role role : roles) {
一个角色可能有多个权限
List<Permission> perList = permissionDao.findByRoleId(role.getId());
for(Permission p : perList) {
装入set集合
permissions.add(p.getPername());
}
}
return permissions;
}
*/
return sInfo;
} return null;
} /**
* 登录认证方法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken auToken) throws AuthenticationException {
// 强制转换
UsernamePasswordToken token = (UsernamePasswordToken) auToken;
// 通过名字查询,用的是token.getUsername,那这个名字是从哪里放进来的呢,是在controller中new出来
// 的token,然后传进去的账户信息,然后在这里get
Admin admin = adminService.findByName(token.getUsername()); if(admin != null) {
// 如果查询得到一个admin就算登录成功 ,因为下面的构造函数会传入账户和密码,然后自动检测
return new SimpleAuthenticationInfo(admin.getName(),admin.getPassword(),getName());
}
return null;
} }
@Controller
public class AdminController { @Inject
private AdminService adminService; @RequestMapping(value="/",method=RequestMethod.POST)
public String login(Admin admin,HttpSession session,RedirectAttributes redirectAttributes) { try {
/* 在这里new出来 UsernamePasswordToken,传入账户信息
当在这里调用login的时候就会自动调用MyShiroRealm中登录认证的那个方法 这个方法是不会抛出异常的,但是我们还是要try catch一下,因为这个方法不能做判断
所以当来到catch的时候就说明登录失败了*/
SecurityUtils.getSubject().login(new UsernamePasswordToken(admin.getName(), admin.getPassword()));
return "redirect:/book/1";
} catch (AuthenticationException e) {
redirectAttributes.addFlashAttribute("message", "账号或密码错误");
return "redirect:/";
} /*
这是以前的方法
Admin currAdmin = adminService.login(admin.getName(),admin.getPassword());
if(currAdmin == null) {
redirectAttributes.addFlashAttribute("message", "账号或密码错误");
return "redirect:/";
} else {
session.setAttribute("curr_admin", currAdmin);
return "redirect:/book";
}*/
} }
jsp中对应的标签
首先导入标签
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!-- 该账户有的角色中存在权限 book:add权限的话就能添加书籍-->
<shiro:hasPermission name="book:add">
<a href="/book/add" class="btn btn-success">添加书籍</a>
</shiro:hasPermission> <table class="table">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名称</th>
<th>作者</th>
<th>出版社</th>
<th>总数量</th>
<th>当前数量</th>
<th>#</th>
</tr>
</thead>
<tbody> <c:forEach items="${bookList }" var="book">
<tr>
<td>${book.code }</td>
<td>${book.name }</td>
<td>${book.author }</td>
<td>${book.publish }</td>
<td>${book.total}</td>
<td>${book.nowcount }</td>
<td>
<shiro:hasPermission name="book:edit">
<a href="/book/edit/${book.id }">修改</a>
</shiro:hasPermission>
<shiro:hasPermission name="book:remove">
<a href="/book/del/${book.id }">删除</a>
</shiro:hasPermission>
</td>
</tr>
</c:forEach>
</tbody>
</table>
这个标签只是在界面上控制不让它显示,但是如果在url上直接进入还是控制不住的,所以要在
applicationContext-shiro.xml 配置,见上...
shiro权限框架的更多相关文章
- Shiro权限框架简介
http://blog.csdn.net/xiaoxian8023/article/details/17892041 Shiro权限框架简介 2014-01-05 23:51 3111人阅读 评论 ...
- 在前后端分离的SpringBoot项目中集成Shiro权限框架
参考[1].在前后端分离的SpringBoot项目中集成Shiro权限框架 参考[2]. Springboot + Vue + shiro 实现前后端分离.权限控制 以及跨域的问题也有涉及
- (转) shiro权限框架详解06-shiro与web项目整合(上)
http://blog.csdn.net/facekbook/article/details/54947730 shiro和web项目整合,实现类似真实项目的应用 本文中使用的项目架构是springM ...
- Apache Shiro权限框架在SpringMVC+Hibernate中的应用
在做网站开发中,用户权限必须要考虑的,权限这个东西很重要,它规定了用户在使用中能进行哪 些操作,和不能进行哪些操作:我们完全可以使用过滤器来进行权限的操作,但是有了权限框架之后,使用起来会非常的方便, ...
- Shiro 权限框架使用总结
我们首先了解下什么是shiro ,Shiro 是 JAVA 世界中新近出现的权限框架,较之 JAAS 和 Spring Security,Shiro 在保持强大功能的同时,还在简单性和灵活性方面拥有巨 ...
- SpringMVC整合Shiro权限框架
尊重原创:http://blog.csdn.net/donggua3694857/article/details/52157313 最近在学习Shiro,首先非常感谢开涛大神的<跟我学Shiro ...
- shiro权限框架(一)
不知不觉接触shiro安全框架都快三个月了,这中间配合项目开发踩过无数的坑.现在回想总结下,也算是一种积累,一种分享.中间有不够完美的地方或者不好的地方,希望大家指出来能一起交流.在这里谢谢开涛老师的 ...
- 关于Apache Shiro权限框架的一些使用误区的解释
多了不说了,进入正题,shiro是个权限框架提供权限管理等功能,网上的教程一般都是互相抄,比如<shiro:principal property="xxx"/>这个标签 ...
- SpringBoot整合Shiro权限框架实战
什么是ACL和RBAC ACL Access Control list:访问控制列表 优点:简单易用,开发便捷 缺点:用户和权限直接挂钩,导致在授予时的复杂性,比较分散,不便于管理 例子:常见的文件系 ...
随机推荐
- eclipse设置web项目发布到tomcat根目录下
如果已经将项目绑定到服务器了,那就先删除服务器. 重新添加项目进服务器,双击 修改下面Server Locations到tomcat目录下 顺带可以修改下右上角的超时设置 再点击下方 这样就可以了.
- golang并发编程
golang并发编程 引子 golang提供了goroutine快速实现并发编程,在实际环境中,如果goroutine中的代码要消耗大量资源时(CPU.内存.带宽等),我们就需要对程序限速,以防止go ...
- 设置Firefox禁用js缓存
让firefox禁用缓存 让Firefox不再使用缓存网站开发时经常会有这样的疑问:为什么修改了代码,刷新了页面还是没有看到改动呢? 其实,可能只是你的Firefox并没有去下载你更新了的文件. 这时 ...
- 超强1000 JQuery插件
转载:超强1000个jquery插件! http://www.cnblogs.com/chu888chu888/archive/2011/12/18/2292014.html
- Oracle DBA常用的系统表
1.2 DBA常用的表1.2.1 dba_开头 dba_users数据库用户信息 dba_segments 表段信息 dba_extents 数据区信息 dba_ob ...
- java线程学习——汉堡销售问题
汉堡店中有一个负责做汉堡的厨师,一个负责销售的营业员,用java线程表示他们的营业过程: 问题原型就是生产者与消费者的问题. 首先定义一个汉堡包箱子类与几个相关的变量类: public class H ...
- iostream.h 和stdio.h区别
stdio.h是C的标准I/O库,是以函数的方式向buffer写入或读取字符.输入输出是这样的printf(...);,scanf(...); iostream是C++的标准I/O库,引入了输入/输出 ...
- 实现JQuery_Accordion功能
1. 添加AJAX引用 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/li ...
- SSAS 发布报错处理方法 Login failed for user 'NT Service\MSSQLServerOLAPService' 28000
Create login and grant access: Open up SQL Server Management Studio [login to the database engine]&g ...
- stack smashing detect错误修正
运行./a.out程序时候出现如下: *** stack smashing detected ***: ./a.out terminated段错误 (核心已转储) 一般这个错误是由于堆栈错误,很可能是 ...