apache shiro整合spring(一)
apache shiro整合spring
maven引入jar包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.3</version>
</dependency>
将shiro配置文件整合到spring体系中
方式一:直接在spring的配置文件中import shiro的配置文件
web.xml中配置spring
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
在spring配置文件中引入shiro配置文件
<import resource="applicationContext-shiro.xml"/>
方式二:直接在web.xml中配置shiro的配置文件
<!-- Spring ApplicationContext 配置文件的路径,可使用通配符,多个路径用,号分隔 此参数用于后面的Spring Context Loader -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext-shiro.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
在web.xml中定义shiro的过滤器
<!-- 这里的filter-name 要和spring 的applicationContext-shiro.xml 里的
org.apache.shiro.spring.web.ShiroFilterFactoryBean 的bean name 相同 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.shiro中定义的filtername bean是要被wen.xml引用的,所以这里的filtername要和shiro中的filtername相同
2.shiro的filter要定义在Struts2的filter之前,否则action无法创建
shiro.xml配置文件(配置校验的策略,哪些校验,哪些放行)
<!-- 安全管理 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- Single realm app. If you have multiple realms, use the 'realms' property instead. -->
<property name="realm" ref="authRealm"/><!-- 引用自定义的realm -->
<!-- 二级缓存 -->
<property name="cacheManager" ref="shiroEhcacheManager"/>
</bean> <!-- 自定义权限认证 -->
<bean id="authRealm" class="com.fyh.www.shiro.AuthRealm">
<!-- <property name="userService" ref="userService"/> -->
<!-- 自定义密码加密算法 -->
<property name="credentialsMatcher" ref="passwordMatcher"/>
</bean> <!-- 设置密码加密策略 md5hash -->
<bean id="passwordMatcher" class="com.fyh.www.shiro.CustomCredentialsMatcher"/> <!-- 此bean要被web.xml引用,和web.xml中的filtername同名 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/index.jsp" /> <!-- 没有认证返回地址 -->
<property name="unauthorizedUrl" value="/index2.jsp" /> <!-- 没有授权返回地址 -->
<property name="filterChainDefinitions">
<value> <!-- **代表任意子目录 -->
/login/** = anon
/user/** = authc,roles[admin]
/test/** = authc,perms[测试用的lkkk]
</value>
</property>
</bean> <!-- 用户授权/认证信息Cache, 采用EhCache 缓存 -->
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
</bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 生成代理,通过代理进行控制 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
</bean> <!-- 安全管理器 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
shiro缓存(ehcache支持ehcache-shiro.xml)
<ehcache updateCheck="false" name="shiroCache"> <defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
</ehcache>
java代码实现
自定义密码认证
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
public boolean doCredentialsMatch(AuthenticationToken token,
AuthenticationInfo info) {
UsernamePasswordToken usertoken = (UsernamePasswordToken) token; //注意token.getPassword()拿到的是一个char[],不能直接用toString(),它底层实现不是我们想的直接字符串,只能强转
Object tokenCredentials = Encrypt.md5(String.valueOf(usertoken.getPassword()),usertoken.getUsername());
Object accountCredentials = getCredentials(info); //将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false
return equals(tokenCredentials, accountCredentials);
}
}
util中定义shiro的MD5加密方法
public class Encrypt {
/*
* 散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,
* 常见的散列算法如MD5、SHA等。一般进行散列时最好提供一个salt(盐),比如加密密码“admin”,
* 产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,
* 可以到一些md5解密网站很容易的通过散列值得到密码“admin”,
* 即如果直接对密码进行散列相对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,
* 如用户名和ID(即盐);这样散列的对象是“密码+用户名+ID”,这样生成的散列值相对来说更难破解。
*/ //高强度加密算法,不可逆
public static String md5(String password, String salt){
return new Md5Hash(password,salt,2).toString();
} public static void main(String[] args) {
System.out.println(new Md5Hash("123456","tony",2).toString());
} }
自定义realm AuthRealm
在认证、授权内部实现机制中都有提到,最终处理都将交给Realm进行处理。
因为在Shiro中,最终是通过Realm来获取应用程序中的用户、角色及权限信息的。
通常情况下,在Realm中会直接从我们的数据源中获取Shiro需要的验证信息。可以说,Realm是专用于安全框架的DAO.
public class AuthRealm extends AuthorizingRealm{
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
} //授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("授权");
//获取当前用户
User user = (User)principals.fromRealm(getName()).iterator().next();
//得到权限字符串
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); Set<Role> roles = user.getRoles();
List<String> list = new ArrayList();
for(Role role :roles){
Set<Module> modules = role.getModules();
for(Module m:modules){
if(m.getCtype()==0){
//说明是主菜单
list.add(m.getCpermission());
}
}
} info.addStringPermissions(list);
return info;
}
//认证 登录
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
System.out.println("认证");
UsernamePasswordToken upToken = (UsernamePasswordToken)token; User user = userService.findUserByName(upToken.getUsername());
if(user==null){
return null;
}else{
AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), getName());
return info;
} } }
修改传统登录为shiro登录
public class LoginAction extends BaseAction { private static final long serialVersionUID = 1L; private String username;
private String password; private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
} public String login() throws Exception {
/*
* shiro登录方式:根据用户名获取密码,密码为null非法用户;有密码检查是否用户填写的密码
* 登录成功后无需往httpsession中存放当前用户,这样就跟web容器绑定,关联太紧密;它自己创建
* subject对象,实现自己的session。这个跟web容器脱离,实现松耦合。
*/ //调用shiro判断当前用户是否是系统用户
Subject subject = SecurityUtils.getSubject(); //得到当前用户
//shiro是将用户录入的登录名和密码(未加密)封装到token对象中
UsernamePasswordToken token = new UsernamePasswordToken(userName,password); try{
subject.login(token); //自动调用AuthRealm.doGetAuthenticationInfo //写seesion,保存当前user对象
User curUser = (User)subject.getPrincipal(); //从shiro中获取当前用户
System.out.println(curUser.getDept().getDeptName()); //让懒加载变成立即加载
Set<Role> roles = curUser.getRoles();
for(Role role :roles){
Set<Module> moduless = role.getModules();
for(Module m :moduless)
System.out.println(m.getName());
}
session.put(SysConstant.CURRENT_USER_INFO, curUser); //Principal 当前用户对象
}catch(Exception ex){
super.put("errorInfo","用户名密码错误,请重新填写!");
ex.printStackTrace(); return "login";
}
return SUCCESS;
} public String logout(){
session.remove(SysConstant.CURRENT_USER_INFO); //删除session
return "logout";
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} }
页面使用shiro标签
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%> <shiro:hasPermission name="sysadmin">
<span id="topmenu" onclick="toModule('sysadmin');">系统管理</span>
</shiro:hasPermission>
apache shiro整合spring(一)的更多相关文章
- apache FtpServer 整合spring部署
我们在项目中可能会出现这样的需求,使用ftp上传很大的文件后对需要对文件进行相应的逻辑处理,这时我们可以使用apache ftpServer来处理这段逻辑,只要我们做相应的部署和编写我们的逻辑代码,这 ...
- 【权限管理】Apache Shiro和Spring Security的对比
一.Shiro简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Secu ...
- Shiro整合Spring
首先需要添加shiro的spring整合包. 要想在WEB应用中整合Spring和Shiro的话,首先需要添加一个由spring代理的过滤器如下: <!-- The filter-name ma ...
- Apache Shiro和Spring Security的详细对比
参考资料: 1)Apache Shiro Apache Shiro:http://shiro.apache.org/ 在Web项目中应用 Apache Shiro:http://www.ibm.com ...
- Apache Shiro 集成Spring(二)
1.依赖: <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-cor ...
- 权限框架Apache Shiro 和 Spring Security
Shiro 首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势.Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证.授 ...
- apache FtpServer整合spring逻辑处理
上面我们的部署工作完成了,那么文件上传下载后,ftpserver会自动相应我们的上传下载操作,也就是说ftpServer服务器会得到触发,那么我们如果要得到文件的一些信息,比如说文件的路径.大小.类型 ...
- Apache Shiro 快速入门教程,shiro 基础教程
第一部分 什么是Apache Shiro 1.什么是 apache shiro : Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 ...
- Shiro学习总结(2)——Apache Shiro快速入门教程
第一部分 什么是Apache Shiro 1.什么是 apache shiro : Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 如同 spr ...
随机推荐
- JavaScript 引用【转】
从一个例子说起: var m ={a:’a’, b:’b’}; var n=m; n.c=’c’; 那么在这个时候 , m.c 也会变成 ’c’! 这个问题在我最开始学习 JS 语言时个人一直处于概念 ...
- Java-性能调优实战(jps、jstack)
找最耗CPU的线程 1. 找出java进程 [ ~]# jps 9939 Resin 9874 WatchdogManager 9926 Jps 2. 找java进程下所有的线程 [ ~]# top ...
- 20145216史婧瑶《Java程序设计》第8周学习总结
20145216 <Java程序设计>第8周学习总结 教材学习内容总结 第十五章 通用API 15.1 日志 java.util.logging 包提供了日志功能相关类与接口,不必额外配置 ...
- xml简单介绍及libmxml编程
今天我们来简单介绍一下,关于xml的一些内容,包括自己编写一些程序进行生成和解析. 首先我们我们还是从xml的演化历史来了解一下它吧. 历史演化 GML: 在20世纪60年代为了促进数据交换和操作,通 ...
- Pycharm安装Python第三方库
转自:http://blog.csdn.net/qiannianguji01/article/details/50397046 除了使用easy_insatll和pip工具安装Python第三方库外还 ...
- 【前端】display: box布局教程 [转]
css display:box 新属性 一.display:box; 在元素上设置该属性,可使其子代排列在同一水平上,类似display:inline-block;. 二.可在其子代设置如下属性 ...
- Python-自省机制
help 如果说能够通过一个函数就能够学会 Python,那这个函数一定就是 Python 提供的第一 个自带说明 help().help 函数的作用就是查看对象的帮组文档.比如: >> ...
- ThinkPHP将上传问件添加到数据库
<?php namespace Home\Controller; /***************** use Think\Controller; ****命名空间****/ class Mes ...
- 感觉Google要搞事情
- LVS-net
一.LVS基本情况 lvs:Linux Virtual Server,是一种负载均衡集群,其主要是由工作在内核的ipvs与用户空间的命令行工具ipvsadm组成.支持TCP,UDP,AH,EST,AH ...