10.2 Web项目,Spring整合Shiro

1、创建maven-web项目

2、导入pomp文件。

除了正常的项目依赖之外,Spring整合Shiro还需要另外导入3个依赖,如下。

    <!--shiro核心包-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.4.1</version>
    </dependency>

    <!--shiro的web包-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>1.4.1</version>
    </dependency>

    <!--shiro和spring的整合包-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.4.1</version>
    </dependency>

3、配置文件

①web.xml文件:配置Shiro过滤器:代理过滤器,还需要在Spring配置文件中配置具体的Bean对象来负责过滤,起到初次拦截用户url地址的作用;过滤客户端发送请求的url地址。

 <!--加载applicationContext.xml,用于扫描springMvc,service,到等配置文件-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-*.xml</param-value>
  </context-param>

  <!--Web项目需要指定监听器,若不配找不到bean对象,用于监听bean对象-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!--配置分发器:DispatcherServlet-->
  <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:springMVC.xml</param-value>
    </init-param>
    <!--服务器启动之后就初始化该Servlet-->
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>springMVC</servlet-name>
    <!--
      *.do/action:避免屏蔽访问静态文件
      /:
       1、访问不了静态资源文件
       2、支持url地址的Restful风格 ?
      /*:错误的写法 定位到jsp上,而不是找Controller
    -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!--
  Shiro过滤器:代理过滤器,还需要在配置文件中再次配置,初次拦截用户的url地址
  过滤客户端发送的请求url地址
  -->
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
      <!--设置成true:由Servlet容器管理过滤器的生命周期-->
      <param-name>targetFilterLifecycle</param-name>
      <param-value>true</param-value>
    </init-param>
    <!--设置Spring容器的filter的bean的id,如果不设置,默认以filter-name的
    值尾bean的id号-->
    <init-param>
      <param-name>targetBeanName</param-name>
      <param-value>shiroFilter</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!--全站编码过滤器,解决post乱码,tomcat7.0以后的版本就不用考虑get乱码-->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <!--要使用的字符集-->
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <!--是否强制设置response的编码为encoding,建议设置为true-->
      <param-name>forceResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

②spring-shiro.xml:这里我们使用自定义Realm实现数据源的管理

  • web.xml中shiroFilter对应的bean:拦截地址

                过滤器链用来拦截和放行请求,ShiroWeb中的所有功能,都是通过各种过滤器(拦截器)来完成的。

【ShiroWeb中的所有功能,都是通过发送请求来完成的】

  • 配置权限管理器(SecurityManager):配置Realm
  • 自定义Realm:配置凭证匹配器,为登录的密码加密服务
  • 配置自定义登出过滤器:实现登出功能
 <!--web.xml中shiroFilter对应的bean-->
    <bean id="shiroFilter"
          class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
        <!--权限管理器-->
        <property name="securityManager" ref="securityManager" />
        <!--认证url地址-->
        <property name="loginUrl" value="/user/login"/>

        <!--认证成功之后,跳转的地址-->
        <property name="successUrl" value="/user/toIndex"/>

        <!--配置表单认证过滤器-->
        <property name="filters">
            <map>
                <!--将自定义的FormAuthenticationFileter注入shiroFilter中-->
                <entry key="authc" value-ref="formAuthenticationFilter"/>
                <!--自定义登出过滤器-->
                <entry key="logout" value-ref="logOutFilter"/>
            </map>
        </property>

        <!--没有权限操作跳转页面url地址-->
        <!--<property name="unauthorizedUrl" value="/unauthorized"/>-->

        <!--过滤器链定义,自上而下顺序执行,一般将/**放在最后-->
        <property name="filterChainDefinitions">
            <value>
                <!--静态资源访问-->
                /image/** = anon
                /jquery/** = anon
                /login.jsp = anon
                /settings/user/logOut = logout
                <!--/toSave = perms["role:add"]-->
                /** = authc
            </value>
        </property>
    </bean>

    <!--配置自定义登出过滤器-->
    <bean id="logOutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
        <property name="redirectUrl" value="/login.jsp"/>
    </bean>

    <!--配置表单过滤器-->
    <bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
        <property name="usernameParam" value="loginAct"/>
        <property name="passwordParam" value="loginPwd"/>
    </bean>

    <!--securityManager权限管理器-->
    <bean id="securityManager"
          class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realms">
            <list>
                <ref bean="customRealm"/>
            </list>
        </property>
    </bean>
    <!--自定义realm-->
    <bean id="customRealm" class="com.bjpowernode.shiro.realm.ShiroRealm">
        <property name="credentialsMatcher" >
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <!--散列算法  加密算法类型MD5-->
                <property name="hashAlgorithmName" value="md5"></property>
                <!--散列次数  加密次数-->
                <property name="hashIterations" value="1"></property>
            </bean>
        </property>
    </bean>
ShiroWeb中常用过滤器

配置缩写

对应的过滤器

功能

anon

AnonymousFilter

指定url可以匿名访问

authc

FormAuthenticationFilter

基于表单的拦截器;如“/**=authc”,如果没有登录会跳到相应的登录页面登录;主要属性:usernameParam:表单提交的用户名参数名( username); passwordParam:表单提交的密码参数名(password); rememberMeParam:表单提交的密码参数名(rememberMe); loginUrl:登录页面地址(/login.jsp);successUrl:登录成功后的默认重定向地址; failureKeyAttribute:登录失败后错误信息存储key(shiroLoginFailure)

logout

LogoutFilter

退出拦截器,主要属性:redirectUrl:退出成功后重定向的地址(/)

user

UserFilter

用户拦截器,用户已经身份验证/记住我登录的都可

perms

PermissionsAuthorizationFilter

角色授权拦截器,验证用户是否拥有所有角色;主要属性: loginUrl:登录页面地址(/login.jsp);unauthorizedUrl:未授权后重定向的地址;示例“/admin/**=roles[admin]”

③springMVC:用于管理视图层 

<!--开启AOP代理功能-->
    <aop:config proxy-target-class="true" />

    <!--开启shiro注解-->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>

    <!--自定义异常-->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <!--转发,默认按视图解析器进行页面跳转-->
                <prop key="org.apache.shiro.authz.UnauthorizedException">/unauthorized</prop>
            </props>
        </property>
    </bean>

    <!--扫描Controller-->
    <context:component-scan
            base-package="com.bjpowernode.shiro.controller" />

    <!--配置处理器适配器和处理器映射器-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <!--json解析器-->
            <bean id="mappingJacksonHttpMessageConverter"
                  class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <!--class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">-->
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json</value>
                        <value>application/xml;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!--处理静态资源文件-->
    <mvc:default-servlet-handler />

    <!--视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp"/>
    </bean>

④spring-service:用于管理业务层

<!--导入dao.xml文件-->
    <import resource="classpath:spring-dao.xml" />

    <!--事务管理器:bean-->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--配置AOP-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(*
        com.bjpowernode.shiro..service.*.*(..))" />
        <aop:advisor advice-ref="trAdvice" pointcut-ref="pointcut" />
    </aop:config>

    <!--配置的事物的传播特性-->
    <tx:advice id="trAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="*bind*" propagation="REQUIRED" />
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="call*" propagation="REQUIRED" />
            <tx:method name="convert*" propagation="REQUIRED" />
            <tx:method name="*Stages*" propagation="REQUIRED" />
            <tx:method name="*" propagation="REQUIRED" read-only="true" />
        </tx:attributes>
    </tx:advice>

⑤spring-dao:用于管理数据层

  <!--配置数据源-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.user}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!--配置SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />

        <!--Mybatis:扫描包,给定实体类别名,默认是类名首字母小写-->
        <property name="typeAliasesPackage" value="com.bjpowernode.shiro.bean" />

        <!--批量扫描映射文件-->
        <property name="mapperLocations" value="classpath:mappers/*.xml" />

        <!--导入SqlMapConfig.xml-->
        <property name="configLocation" value="classpath:Mybatis/SqlMapConfig.xml" />
    </bean>

    <!--
        扫描mapper接口,Spring框架给持久层接口创建代理子类
        tk.mybatis.spring.mapper.MapperScannerConfigurer
        既能使用传统的Mybatis,又能使用tkMapper
        org.mybatis.spring.mapper.MapperScannerConfigurer
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.bjpowernode.shiro.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

⑥spring-dao:用于扫描包,管理Bean对象

<!--引入db.properties-->
    <context:property-placeholder location="classpath:Mybatis/db.properties"/>

    <!--扫描包,管理Bean对象-->
    <context:component-scan base-package="com.bjpowernode.shiro"/>

    <import resource="classpath:spring-service.xml"/>

四 、ShiroWeb项目认证

【认证流程:】
用户在登录界面输入身份和凭证之后,发送认证请求,FormAuthenticationFilter拦截用户请求会把用户输入的身份和凭证获取到传给
Realm,Realm进行数据校验,校验完毕后和认证器一起完成认证操作,如果身份错误,跳转到配置文件中按认证地址进行拦截,如果认证失败,会把异常类的字节码路径放入到 request 域中,属性名叫作 shiroLoginFilter

区别于正常的Web项目,登录后先进入 Controller,ShiroWeb 项目是先进入 Realm,然后将异常抛出到 Controller

【注意:】

此处页面使用的方式是传统方式,即未使用异步方式。

  • 表单提交地址  action:spring-shiro中过滤器的认证地址

  <!--认证url地址-->
  <property name="loginUrl" value="/user/login"/>

  • 提交方式  method=post
  • 传统方式根据 name 获取值,表单向的名字默认分别是username和password,若名字不对,获取不到。可以通过在 spring-shiro.xml 配置文件中配置,配置表单认证过滤器
  • button 事件 type 类型改成 button——>sbumit

权限校验
用户操作系统资源,发送url请求,如果认证通过后,配置PermissionsAuthorizationFilter
进行权限拦截,判断用户的权限中的权限标识符有没有指定合法的标识符(查询数据库[Realm完成])


Shiro认证中编码式与注解式的区别:

  • 编码式
  1.   通过过滤器链进行拦截: /toSave = perms["role:add"]
  2. 根据 spring-shiro 中<!--没有权限操作跳转页面url地址-->的地址跳转到未授权的页面
  3. 但是项目中的请求太多就不方便              
  • 注解式
  1.  将 shiroFilter 中的  <!--没有权限操作跳转页面url地址-->   删除
  2. 在 Controller 对应的方法上加入注解 @RequiresPermissions("role:add")
  3. 注解版本 shiro 没有处理错误请求,需要使用 springMVC 中的自定义异常
 <!--自定义异常-->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <!--转发,默认按视图解析器进行页面跳转-->
                <prop key="org.apache.shiro.authz.UnauthorizedException">/unauthorized</prop>
            </props>
        </property>
    </bean>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值