专栏首页Java技术分享第八章:Shiro和Spring的集成——深入浅出学Shiro细粒度权限开发框架
原创

第八章:Shiro和Spring的集成——深入浅出学Shiro细粒度权限开发框架

Standalone Applications

Shiro 应用程序需要一个具有单例SecurityManager 实例的应用程序。请注意,这不会是一个静态的单例,但应该只有一个应用程序能够使用的实例,无论它是否是静态单例的。

在Spring 应用程序中启用应用程序单例SecurityManager的最简单配置:

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">

  <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>

  <property name="arguments" ref="securityManager"/>

</bean>

<bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">

      <property name="realm" ref="myRealm"/>  

</bean>

<bean id="myRealm" class="org.apache.shiro.realm.text.IniRealm">

  <property name="resourcePath" value="D:/wp/src/TestShiro.ini"></property> 

</bean>

Wb应用

在web.xml中

<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>

在spring的applicationContext.xml 文件中,定义web 支持的SecurityManager 和'shiroFilter' bean 将会被web.xml 引用

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

    <property name="securityManager" ref="securityManager"/>

    <!—以下为可选配置,请按照实际项目需要进行配置-->

    <property name="loginUrl" value="/login.jsp"/>

    <property name="unauthorizedUrl" value="/unauthorized.jsp"/>

    <!– filters属性也是可选的,用来声明一些可以在filterChainDefinitions里面使用的filter。如果你声明的filter名称是shiro默认有的,那么将会覆盖默认的filter -->

    <property name="filters">

        <util:map>

   <!– 比如:这个filter是shiro里面有的,那么自定义的filter将会覆盖默认的-->

            <entry key="authc" value-ref="formAuthenticationFilter"/>

            <!– 比如:这个filter是项目新加的filter-->

            <entry key="jCaptchaValidate" value-ref="jCaptchaValidateFilter"/>

        </util:map>

    </property>

    <property name="filterChainDefinitions">

        <value>

  <!— 这里配置urls,对不同的url配置需要经过的filter-->

            /jcaptcha* = anon

            /logout = logout

            /login = jCaptchaValidate,authc

        </value>

    </property>

</bean>

<!--替换默认的form 验证过滤器-->

<bean id="formAuthenticationFilter" class="cn.javass.CustomFormAuthenticationFilter">

    ......

</bean>

<!—然后就是SecurityManger、Realms等-->

<bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">

      <property name="realm" ref="myRealm"/>  

</bean>

<bean id="myRealm" class="org.apache.shiro.realm.text.IniRealm">

  <property name="resourcePath" value="D:/wp/src/TestShiro.ini"></property> 

</bean>

n开启注解

<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>

和Struts2+Spring3的集成

n构建一个动态web工程,然后把包加好,web.xml的配置如下:

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

  metadata-complete="true" version="3.0">

  <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>

  <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>

  <filter>

  <filter-name>struts2</filter-name>

  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

  </filter>

  <filter-mapping>

  <filter-name>struts2</filter-name>

  <url-pattern>/*</url-pattern>

  </filter-mapping> 

</web-app>

Struts2的配置比较简单:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

  <constant name="struts.devMode" value="true"/>

    <constant name="struts.locale" value="zh_CN"/>

    <constant name="struts.i18n.encoding" value="utf-8"/>

</struts>

nSpring的配置文件基本就是前面讲到的,合在一起了,示例如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  ">

  <aop:aspectj-autoproxy proxy-target-class="true"/>

  <tx:annotation-driven transaction-manager="txManager" />

  <context:component-scan base-package="cn.javass"></context:component-scan>

  <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>

  <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">

  <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>

  <property name="arguments" ref="securityManager"/>

  </bean>

  <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

  <property name="securityManager" ref="securityManager" />

  <property name="filterChainDefinitions">

  <value>

  /userAction!toList.action = roles[role1]

  </value>

  </property>

  </bean>

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 

      <property name="cacheManager" ref="cacheManager"/> 

        <property name="realm" ref="myRealm"/> 

        <property name="sessionManager" ref="sessionManager"/>  

  </bean>

  <bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager"></bean>

  <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" />

  <bean id="myRealm" class="org.apache.shiro.realm.text.IniRealm">

  <property name="resourcePath" value="D:/shiroweb/src/TestShiro.ini"></property> 

  </bean>

</beans>

对应的TestShiro.int做了足够的简化,示例如下:

[users]

javass=cc,role1

[roles]

role1 = p1,p2

写一个LoginAction,示例如下:

@Action(

  value="/login",

  results={

  @Result(name = "toList", location = "/list.jsp"),

  @Result(name = "success", location = "/ok.jsp")})

public class LoginAction extends ActionSupport{

  private String userId = "";

  private String pwd = "";

  //getter setter

  public String execute(){

  UsernamePasswordToken token = new UsernamePasswordToken(userId,pwd); 

  token.setRememberMe(true);

  Subject currentUser = SecurityUtils.getSubject(); 

  currentUser.login(token);

  System.out.println(currentUser.getPrincipal()+"====has r1 === "+currentUser.hasRole("role1"));

  return this.SUCCESS;

  }

}

写一个UserAction进行权限测试,示例如下:

@Action(

  value="/user",

  results={

  @Result(name = "toList", location = "/list.jsp"),

  @Result(name = "success", location = "/ok.jsp")

  }

)

public class UserAction extends ActionSupport{

  @RequiresPermissions({"p1"})

  public String execute(){

  Subject currentUser = SecurityUtils.getSubject();

  System.out.println("now user===="+currentUser.getPrincipal()+" ,role=="+currentUser.hasRole("role1")+" , p=="+currentUser.isPermitted("p1"));

  return "toList";

  }

}

和Struts2集成的时候,如果使用注解的方式进行权限判断,而struts2又使用spring的依赖注入逻辑层的对象的时候,是存在bug的,可能会导致取不到注入的对象。这个bug是struts2的,主要是都是使用的aop,有一些冲突。需要修正,可以加入我们修正的代码包。同时要注意:需要使用getter/setter来注入,不要使用属性的方式。

和 SpringMVC+Spring3 的集成

构建一个动态web工程,然后把包加好,web.xml的配置如下:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

  id="WebApp_ID" version="3.0"  metadata-complete="true"> 

  <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>

  <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>

  <servlet>

  <servlet-name>springmvc</servlet-name>

  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

  <init-param>

  <param-name>contextConfigLocation</param-name>

  <param-value>classpath:spring-servlet-config.xml</param-value>

  </init-param>

  <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>

  <servlet-name>springmvc</servlet-name>

  <url-pattern>/</url-pattern>

  </servlet-mapping>

</web-app>

对应的TestShiro.ini跟前面struts2集成是一样的

Spring的配置文件基本跟前面那个差不多,只是有部分配置移到springmvc的配置文件中了,示例如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xmlns:context="http://www.springframework.org/schema/context"

  xmlns:aop="http://www.springframework.org/schema/aop"

  xmlns:tx="http://www.springframework.org/schema/tx"

  xsi:schemaLocation="

  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd

  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

  "

  >

  <context:component-scan base-package="cn.javass">

  <context:exclude-filter type="annotation"

  expression="org.springframework.stereotype.Controller" />

  </context:component-scan> 

  <aop:aspectj-autoproxy proxy-target-class="true"/>

� k; o �� �ne :宋体;mso-ascii-font-family: 宋体;mso-fareast-font-family:宋体;mso-bidi-font-family:+mn-cs;color:black; mso-color-index:1;mso-font-kerning:12.0pt;language:en-US'>  <servlet-mapping>

  <servlet-name>springmvc</servlet-name>

  <url-pattern>/</url-pattern>

  </servlet-mapping>

</web-app>

n对应的TestShiro.ini跟前面struts2集成是一样的

nSpring的配置文件基本跟前面那个差不多,只是有部分配置移到springmvc的配置文件中了,示例如下:

  <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

  <property name="securityManager" ref="securityManager" />

  <property name="filterChainDefinitions">

  <value>

  </value>

  </property>

  </bean>

  <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 

      <property name="cacheManager" ref="cacheManager"/> 

        <property name="realm" ref="myRealm"/> 

        <property name="sessionManager" ref="sessionManager"/>

  </bean>

  <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"></bean>

  <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" />

  <bean id="myRealm" class="org.apache.shiro.realm.text.IniRealm">

  <property name="resourcePath" value="D:/newlesson/shiro/webwp/mvc/src/TestShiro.ini"></property> 

  </bean>

 </beans>

Springmvc的配置文件,示例如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"

  xmlns:context="http://www.springframework.org/schema/context"

  xmlns:mvc="http://www.springframework.org/schema/mvc"

  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/mvc

       http://www.springframework.org/schema/mvc/spring-mvc.xsd"

  default-lazy-init="true">

  <!-- 开启controller注解支持 -->

  <context:component-scan base-package="cn.javass"

  use-default-filters="false">

  <context:include-filter type="annotation"

  expression="org.springframework.stereotype.Controller" />

  </context:component-scan>

  <!-- 会自动注册了validator ConversionService -->

  <mvc:annotation-driven ></mvc:annotation-driven>

  <mvc:default-servlet-handler />

  <mvc:resources mapping="/static/**" location="/WEB-INF/static/" />

  <!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用html)- -->

  <bean id="defaultViewResolver"

  class="org.springframework.web.servlet.view.InternalResourceViewResolver">

  <property name="viewClass"  value="org.springframework.web.servlet.view.JstlView" />

  <property name="contentType" value="text/html" />

  <property name="prefix" value="/WEB-INF/jsp/" />

  <property name="suffix" value=".jsp" />

  </bean>

  <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>

  <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">

  <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>

  <property name="arguments" ref="securityManager"/>

  </bean>

</beans>

简单的HelloWorldController,示例如下:

@Controller

public class HelloWorldController {

  @Autowired

  private MyService ms = null;

  @RequestMapping("/login")

public String login(@RequestParam("username") String username,@RequestParam("password") String password) {

  System.out.println("user==" +username+" , pwd=="+password);

  UsernamePasswordToken token = new UsernamePasswordToken(username,password); 

  token.setRememberMe(true);

  Subject currentUser = SecurityUtils.getSubject(); 

  currentUser.login(token);

  System.out.println(currentUser.getPrincipal()+"====has r1 === "+currentUser.hasRole("r1")+" , isau=="+currentUser.isAuthenticated());

  return "login";

  }

  @RequestMapping("/h3")

  @RequiresAuthentication

  @RequiresPermissions({"p1"})

  public String h3(@ModelAttribute("nn")String nn ) {

  ms.doService();

  System.out.println("nn=="+SecurityUtils.getSubject().isAuthenticated());

  return "ok";

  }

}

对应的MyService非常简单,示例如下:

@Service

public class MyService {

  public void doService(){

  System.out.println("now do Service");

  }

}

再来一个Login.jsp,就可以测试了,示例如下:

<form action="/shirolessonmvc/login" method="post">

<table>

  <tr>

  <td>用户名:</td>

  <td><input type="text" name="username"></input></td>

  </tr>

  <tr>

  <td>密码:</td>

  <td><input type="password" name="password"></input></td>

  </tr>

  <tr>

  <td>记住我</td>

  <td><input type="checkbox" name="rememberMe" checked/></td>

  <td><input type="submit"></td>

  </tr>

</table>  </form>

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 第八章:Shiro和Spring的集成——深入浅出学Shiro细粒度权限开发框架

    Standalone Applications nShiro 应用程序需要一个具有单例SecurityManager 实例的应用程序。请注意,这不会是一个静态的...

    MonroeCode
  • spring 监听器

    package net.blissmall.system.climborder.web.controller; import net.blissmall.sys...

    MonroeCode
  • Shiro 权限框架使用总结

    我们首先了解下什么是shiro ,Shiro 是 JAVA 世界中新近出现的权限框架,较之 JAAS 和 Spring Security,Shiro 在保持强大...

    MonroeCode
  • 第八章:Shiro和Spring的集成——深入浅出学Shiro细粒度权限开发框架

    Standalone Applications nShiro 应用程序需要一个具有单例SecurityManager 实例的应用程序。请注意,这不会是一个静态的...

    MonroeCode
  • SSM 框架快速整合实例--学生查询

    SSM 框架即 Spring 框架、SpringMVC 框架、MyBatis 框架,关于这几个框架的基础和入门程序,我前面已经写过几篇文章作为基础和入门介绍了。

    compassblog
  • SSM 框架快速整合实例--学生查询

    SSM 框架即 Spring 框架、SpringMVC 框架、MyBatis 框架,关于这几个框架的基础和入门程序,我前面已经写过几篇文章作为基础和入门介绍了。...

    compassblog
  • SpringMvc学习-环境搭建

    最近在学习SpringMVC,首先来说说SpringMVC项目的搭建。 1.SpringMVC简介 spring Web MVC是一种基于Java的实现了Web...

    水击三千
  • Spring+SpringMVC+MyBatis+easyUI整合基础篇(三)搭建步骤

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载。 框架介绍 Spring...

    我是十三
  • SpringMVC笔记

    在方法参数前加上**@PathVariable**注解,让方法参数的值对应绑定到一个URL模板变量上

    菜鸟雷
  • SSM框架整合 原

    wuweixiang

扫码关注云+社区

领取腾讯云代金券