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(一)的更多相关文章

  1. apache FtpServer 整合spring部署

    我们在项目中可能会出现这样的需求,使用ftp上传很大的文件后对需要对文件进行相应的逻辑处理,这时我们可以使用apache ftpServer来处理这段逻辑,只要我们做相应的部署和编写我们的逻辑代码,这 ...

  2. 【权限管理】Apache Shiro和Spring Security的对比

    一.Shiro简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Secu ...

  3. Shiro整合Spring

    首先需要添加shiro的spring整合包. 要想在WEB应用中整合Spring和Shiro的话,首先需要添加一个由spring代理的过滤器如下: <!-- The filter-name ma ...

  4. Apache Shiro和Spring Security的详细对比

    参考资料: 1)Apache Shiro Apache Shiro:http://shiro.apache.org/ 在Web项目中应用 Apache Shiro:http://www.ibm.com ...

  5. Apache Shiro 集成Spring(二)

    1.依赖: <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-cor ...

  6. 权限框架Apache Shiro 和 Spring Security

    Shiro 首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势.Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证.授 ...

  7. apache FtpServer整合spring逻辑处理

    上面我们的部署工作完成了,那么文件上传下载后,ftpserver会自动相应我们的上传下载操作,也就是说ftpServer服务器会得到触发,那么我们如果要得到文件的一些信息,比如说文件的路径.大小.类型 ...

  8. Apache Shiro 快速入门教程,shiro 基础教程

    第一部分 什么是Apache Shiro     1.什么是 apache shiro :   Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 ...

  9. Shiro学习总结(2)——Apache Shiro快速入门教程

    第一部分 什么是Apache Shiro 1.什么是 apache shiro : Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 如同 spr ...

随机推荐

  1. idea打jar包-MapReduce作业提交到hadoop集群执行

    https://blog.csdn.net/jiaotangX/article/details/78661862 https://liushilang.iteye.com/blog/2093173

  2. spoj1812 LCS2 - Longest Common Substring II

    地址:http://www.spoj.com/problems/LCS2/ 题面: LCS2 - Longest Common Substring II no tags  A string is fi ...

  3. ASP.NET Core EF 查询获取导航属性值,使用Include封装

    // 引用 using Microsoft.EntityFrameworkCore; // 摘要: // Specifies related entities to include in the qu ...

  4. eclipse 创建jsp报错

  5. IDEA 2018.2破解

    最新的IDEA激活方式 使用网上传统的那种输入网址的方式激活不了,使用http://idea.lanyus.com/这个网站提供的工具进行 1.进入hosts文件中:C:\Windows\System ...

  6. 让div水平垂直居中的几种方法

    最近,公司招了一批新人,吃饭的时候恰好碰到一个新同事,就跟他聊了起来.听他说了主管面试的时候出的一些问题,其中一个问题我印象特别深刻,因为,我当年进来的时候,也被问到这个问题.虽然这个问题已经问烂了, ...

  7. c/c++调用dll

    1.lib.h 1 #ifndef LIB_H 2 #define LIB_H 3 4 #include <windows.h> 5 #include <iostream> 6 ...

  8. 20145312 实验三《敏捷开发与XP实践》

    20145312 实验三<敏捷开发与XP实践> 实验内容 使用 git 上传代码 使用 git 相互更改代码 与20145318同学一组,使用git相互更改代码 同组实验报告链接:http ...

  9. linux内核第二周

    chapter 1 知识点梳理 (一)计算机是如何工作的?(总结)——三个法宝 ①存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: ②函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语 ...

  10. CNN笔记:通俗理解卷积神经网络【转】

    本文转载自:https://blog.csdn.net/v_july_v/article/details/51812459 通俗理解卷积神经网络(cs231n与5月dl班课程笔记) 1 前言 2012 ...