关于项目的安全保护,我一直想找一个简单配置就能达到目的的方法,自从接触了shiro,这个目标总算达成了,以下结合我使用shiro的经验,谈谈比较轻便地集成该功能。

首先我们先了解一下shiro是什么。

apache shiro 是一个功能强大和易于使用的Java安全框架,为开发人员提供一个直观而全面的的解决方案的认证,授权,加密,会话管理。

其实按照我个人的理解,就是个过滤器,按照配置(或者注解)的规则进行权限验证。

我的项目基于maven管理依赖jar包,首先把apache shiro相关需要用到的jar引入:

<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.1</version>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.1</version>
</dependency>

其中shiro-web和shiro-spring必须,如果要缓存权限的话,就引入shiro-ehcache,后边会详细说道shiro-ehcache的使用。

看一下login.action里是如何实现用户登录写入的,获取用户表单信息以及查询数据库验证就不说了,直接上关键代码:

            //验证用户信息后进行token写入,这里为了简单,我把用户的id和姓名作为token的username和password
UsernamePasswordToken token = new UsernamePasswordToken(m.getId()
.toString(), m.getUsername());
Subject subject1 = SecurityUtils.getSubject();
subject1.login(token);
subject1.getSession();

既然是个过滤器,那我们就看一下这个过滤器的写法:

package com.airfey.tech.nuo.action.shiro.filter;

import java.io.IOException;
import java.security.Principal; import javax.annotation.Resource;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject; import com.airfey.tech.nuo.common.security.MD5;
import com.airfey.tech.nuo.core.domain.Manager;
import com.airfey.tech.nuo.core.service.ManagerService; public class shiroFilter implements Filter {
//管理员用户service
@Resource
private ManagerService managerService; @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException { Subject subjects = SecurityUtils.getSubject(); HttpServletRequest requestHttp = (HttpServletRequest) request;
HttpServletResponse responseHttp = (HttpServletResponse) response; Principal principal = requestHttp.getUserPrincipal();
if (null != principal) {
//principal.getName()里保存的是用户的id,就是上边登录处token里的信息
System.out.println(principal.getName());
Manager m = managerService.findOne(Long.parseLong(principal
.getName()));
if (null != m && 1 == m.getAudit()) {
UsernamePasswordToken token = new UsernamePasswordToken(
m.getId(), m.getId());//作为例子,这里我只是把用户id放进了token,你可以修改成其它复杂点的信息
Subject subject1 = SecurityUtils.getSubject();
subject1.login(token);
subject1.getSession();
} else {
if (subjects != null) {
subjects.logout();
}
}
} chain.doFilter(requestHttp, responseHttp); } @Override
public void destroy() { } }

至此,可以说登录和过滤器已经完成了。然后就进行web.xml和spring文件以及权限验证的实现。

1、在web.xml里加入shiro的过滤器配置:

<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

此过滤器要位于所有过滤器的前面。

2、权限验证代码实现,我们写一个realm类集成shiro的AuthorizingRealm

package com.airfey.tech.nuo.action.shiro.realm;

import javax.annotation.Resource;

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.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection; public class ShiroRealm extends AuthorizingRealm { @Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
if (principals == null) {
throw new AuthorizationException(
"PrincipalCollection method argument cannot be null.");
}
String username = (String) getAvailablePrincipal(principals);
System.out.println("-------------------" + username);//输出的其实是用户id SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 增加默认角色
info.addRole("ROLE_USER");
/*以下可以从数据库获取用户的角色以及权限信息,获取到的信息添加入info即可,具体获取数据库的代码我就省略了*/
// // 增加自定义角色
// if (null != userInfo.getRoleList()) {
// for (RoleInfo roleInfo : userInfo.getRoleList()) {
// if (null != roleInfo.getName()
// && !"".equals(roleInfo.getName())) {
// info.addRole(roleInfo.getName());
// }
// }
// }
// if (null != userInfo.getModuleInfo()) {
// for (ModuleInfo moduleInfo : userInfo.getModuleInfo()) {
// if (null != moduleInfo.getGuid()
// && !"".equals(moduleInfo.getGuid())) {
// info.addStringPermission(moduleInfo.getGuid());
// }
// }
// } return info; } @Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
String userName = token.getUsername();
if (userName != null && !"".equals(userName)) { return new SimpleAuthenticationInfo(token.getPrincipal(),
token.getPassword(), token.getUsername());
}
return null;
} /**
* 清空用户关联权限认证,待下次使用时重新加载。
*
* @param principal
*/
public void clearCachedAuthorizationInfo(String principal) {
SimplePrincipalCollection principals = new SimplePrincipalCollection(
principal, getName());
clearCachedAuthorizationInfo(principals);
} /**
* 清空所有关联认证
*/
public void clearAllCachedAuthorizationInfo() {
Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
if (cache != null) {
for (Object key : cache.keys()) {
cache.remove(key);
}
}
}
}

3、applicationContext.xml的配置 (这里只保留了shiro相关的信息)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd"> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="successUrl" value="/manage/index.do" />
<property name="loginUrl" value="/manage/login.do" />
<property name="unauthorizedUrl" value="/manage/401.html" />
<property name="filters">
<map>
<entry key="authc" value-ref="shiro"></entry>
</map>
</property>
<property name="filterChainDefinitions">
<value>
/manage/admin.html = authc,perms[shiro_admin:view]
/manage/user.html=authc,perms[shiro_user:view]
/manage/login.do=anon
/manage/401.html=anon
/manage/js/**=anon
/manage/img/**=anon
/manage/kindeditor/**=anon
/manage/**=authc,roles["ROLE_USER"]
/**=anon
</value>
</property>
</bean>
<bean id="shiro" class="com.airfey.tech.nuo.action.shiro.filter.shiroFilter"> </bean>
<bean id="shiroRealm" class="com.airfey.tech.nuo.action.shiro.realm.ShiroRealm" />
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="shiroRealm" />
<property name="cacheManager" ref="shiroEhcacheManager" />
</bean> <!-- 用户授权信息Cache, 采用EhCache,需要的话就配置上此信息 -->
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />
</bean> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean> </beans>

验证规则里如下让静态文件比如js img 目录配置上anon

/manage/admin.html = authc,perms[shiro_admin:view]

/manage/user.html=authc,perms[shiro_user:view]

/manage/login.do=anon

/manage/401.html=anon

/manage/js/**=anon

/manage/img/**=anon

/manage/kindeditor/**=anon

/manage/**=authc,roles["ROLE_USER"]

/**=anon

结束,收工。好久不写这么长的博文了,敲起来真费劲。原创文章,文中难免有遗漏或者错误之处,请指正。

作者:碧血黄沙
出处:http://www.cnblogs.com/airfey/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

基于spring框架的apache shiro简单集成的更多相关文章

  1. 基于Spring框架的简单多数据源切换解决办法

    基于Spring框架的简单多数据源切换解决办法 Spring框架JDBC包提供了一个抽象类AbstractRoutingDataSource提供了动态切换数据库的基础方法.我们仅仅需要实现一个简单的数 ...

  2. 基于Spring框架应用的权限控制系统的研究和实现

    摘 要: Spring框架是一个优秀的多层J2EE系统框架,Spring本身没有提供对系统的安全性支持.Acegi是基于Spring IOC 和 AOP机制实现的一个安全框架.本文探讨了Acegi安全 ...

  3. web应用安全框架选型:Spring Security与Apache Shiro

    一. SpringSecurity 框架简介 官网:https://projects.spring.io/spring-security/ 源代码: https://github.com/spring ...

  4. 基于Spring Aop实现类似shiro的简单权限校验功能

    在我们的web开发过程中,经常需要用到功能权限校验,验证用户是否有某个角色或者权限,目前有很多框架,如Shiro Shiro有基于自定义登录界面的版本,也有基于CAS登录的版本,目前我们的系统是基于C ...

  5. 基于Spring框架的Shiro配置

    一.在web.xml中添加shiro过滤器  <!-- Shiro filter--> <filter> <filter-name>shiroFilter</ ...

  6. 第一次玩博客,今天被安利了一个很方便JDBC的基于Spring框架的一个叫SimpleInsert的类,现在就来简单介绍一下

    首先先对这段代码的简单介绍,我之前在需要操作JDBC的时候总是会因为经常要重新写SQL语句感到很麻烦.所以就能拿则拿不能拿的就简单地封装了一下. 首先是Insert.Spring框架的JDBC包里面的 ...

  7. 基于Spring框架的Shiro配置(转发:http://kdboy.iteye.com/blog/1103794)

    一.在web.xml中添加shiro过滤器 <!-- Shiro filter--> <filter> <filter-name>shiroFilter</f ...

  8. Java开源安全框架之Apache Shiro

    APACHE SHIRO安全框架 1      背景 Shiro项目始于2003年初,当时它叫JSecurity项目,当时对于Java应用开发人员没有太多的安全替代方案,始终被一个叫JAAS(Java ...

  9. Spring框架-IOC和AOP简单总结

    参考博客: https://blog.csdn.net/qq_22583741/article/details/79589910 1.Spring框架是什么,为什么,怎么用 1.1 Spring框架是 ...

随机推荐

  1. MySQL基础之 排序与限制,聚合

    排序与限制 ORDER BY 作用:取出按照某个字段进行排序后的记录结果集. 配合:常与DESC  和ASC一块使用:默认是ASC,表示升序.DESC表示降序 LIMIT 作用:用于显示数据的一部分记 ...

  2. 2018.08.31 19:41 自学go语言

    有的人是从最基础的开始学,而我却是从最简单开始学,学着调试,学着编程,其实我也是编程小白,好多的不懂,我不明白很多都可以用云完成了,为什么还要继续自己编程,不明白,但是有需求吧,有需求是件好事情,说明 ...

  3. 【adb命令】在cmd窗口中使用adb install命令安装 中文名字apk报错的解决办法

    1.在cmd窗口中使用adb install命令安装中文名字apk报错,安装英文名字apk就正常,详细报错如下图: 2.查看adb版本号:adb version 3.怀疑是adb版本的原因,尝试换个最 ...

  4. jQuery----各版本

    jQuery是一套跨浏览器的JavaScript库,简化HTML与JavaScript之间的操作.由John Resig在2006年1月的BarCamp NYC上发布第一个版本.目前是由 Dave M ...

  5. js面对对象编程(二):属性和闭包

    上篇博客中解说了一些js对象的基本概念和使用方法.这篇博客解说一下js属性方面的:公有属性.私有属性,特权方法. 假设学过java.公有属性.私有属性,特权方法(即能够訪问和设置私有属性的方法)一定非 ...

  6. Spring-IOC RootBeanDefinition源码分析

    GenericBeanDefinition是一站式的标准bean definition,除了具有指定类.可选的构造参数值和属性参数这些其它bean definition一样的特性外,它还具有通过par ...

  7. Oracle 12C Data Gurad RAC TO RAC

    Oracle 12C RAC TO RAC Data Guard on RHEL7 0.环境说明   primary db physical standby 操作系统 rhel7 x86_64 rhe ...

  8. 【转】使用程序修改系统(IE)代理设置

    文章都是发布在github再转到这边的,这边格式可能会乱掉.博客地址:benqy.com 这是本人在做的一个前端开发调试工具(HttpMock),功能是web服务器+http日记+http代理(类似f ...

  9. windows 下配置 Nginx 常见问题

    因为最近的项目需要用到负载均衡,不用考虑,当然用大名鼎鼎的Nginx啦.至于Nginx的介绍,这里就不多说了,直接进入主题如何在Windows下配置. 我的系统是win7旗舰版的,到官网下载最新版本 ...

  10. Posts Tagged ‘This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register问题的解决办法

    HowTo Install redhat package with YUM command without RHN February 26, 2014 in Redhat / Linux Tips a ...