由于shiro在web.xml中配置属于过滤器,其中在web.xml中的加载顺序为: <context-param>(上下文) > listener > filter > servlet>interceptor,

可见shiroFilter是早于SpringMVC的,所以Controller无法注册service,同时Realm中注册的service为空,我百度的各种方法都试过了仍然不好用。

最终我把spring整合shiro的配置直接全部拉到了spring.xml(整合mabatis,redis)配置文件的最下面。

如果大家想看可以参考下面

spring.xml

<?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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"default-autowire="byName" default-lazy-init="false"><!-- 配置注解处理器 --><context:annotation-config/><!-- 自动注册service --><context:component-scan base-package="com.smart.service"/><!--扫描redis配置文件--><context:property-placeholder ignore-unresolvable="true" location="classpath:redis.properties"/><!--Spring整合Redis--><!--设置连接池--><bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"><!-- 最大空闲连接数 --><property name="maxIdle" value="${redis.maxIdle}"/><!-- 最大连接数 --><property name="maxTotal" value="${redis.maxTotal}" /><!-- 每次释放连接的最大数目 --><property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" /><!-- 释放连接的扫描间隔(毫秒) --><property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" /><!-- 连接最小空闲时间 --><property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" /><!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 --><property name="maxWaitMillis" value="${redis.maxWaitMillis}" /><!-- 在获取连接的时候检查有效性, 默认false --><property name="testOnBorrow" value="${redis.testOnBorrow}" /><property name="testOnReturn" value="${redis.testOnReturn}" /><!-- 在空闲时检查有效性, 默认false --><property name="testWhileIdle" value="${redis.testWhileIdle}" /><!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true --><property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" /></bean><!-- jedis客户端单机版 --><bean id="redisClient" class="redis.clients.jedis.JedisPool"><constructor-arg name="host" value="${redis.host}"></constructor-arg><constructor-arg name="port" value="${redis.port}"></constructor-arg><constructor-arg name="password" value="${redis.password}"></constructor-arg><constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg><constructor-arg name="timeout" value="100000"></constructor-arg></bean><bean id="JedisClient" class="com.smart.redis.JedisClientSingle"/><!--Spring整合Mabatis--><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver"p:url="jdbc:mysql://localhost:3306/bookmanager?characterEncoding=utf8"p:username="root" p:password="960521" p:maxActive="10" p:maxIdle="10"p:validationQuery="SELECT 1"  p:testOnBorrow="true"></bean><!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--dataSource属性指定要用到的连接池--><property name="dataSource" ref="dataSource" /><!--configLocation属性指定mybatis的核心配置文件--><property name="configLocation" value="classpath:mybatis.xml" /><!-- 所有配置的mapper文件 --><property name="mapperLocations" value="classpath*:mapper/*.xml" /></bean><!-- DAO接口所在包名,Spring会自动查找其下的类 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.smart.dao"/></bean><!-- 开启注解方式声明事务 --><tx:annotation-driven transaction-manager="transactionManager" />

<!--这里开始整合redis--><!--Spring整合shiro--><!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><!-- 调用我们配置的权限管理器 --><property name="securityManager" ref="securityManager" /><!-- 配置我们的登录请求地址 --><property name="loginUrl" value="/login" /><!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 --><property name="successUrl" value="/maSystem" /><!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 --><property name="unauthorizedUrl" value="/error" /><property name="filters"><util:map><entry key="logout" value-ref="logoutFilter" /></util:map></property><!-- 权限配置 --><property name="filterChainDefinitions"><value><!-- anon表示此地址不需要任何权限即可访问 -->/error=anon/meList=anon/maSystem=anon/login=anon/listBook.do=anon/UserType.do=anon/style/**=anon/logout=logout<!--所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/login -->/** = authc</value></property></bean><bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter"><property name="redirectUrl" value="/login" /></bean><!-- 凭证匹配器<bean id="passwordMatcher" class="org.apache.shiro.authc.credential.PasswordMatcher"><property name="passwordService" ref="passwordService" /></bean><bean id="passwordService"class="org.apache.shiro.authc.credential.DefaultPasswordService"><property name="hashService" ref="hashService"></property><property name="hashFormat" ref="hashFormat"></property><property name="hashFormatFactory" ref="hashFormatFactory"></property></bean><bean id="hashService" class="org.apache.shiro.crypto.hash.DefaultHashService"></bean><bean id="hashFormat" class="org.apache.shiro.crypto.hash.format.Shiro1CryptFormat"></bean><bean id="hashFormatFactory"class="org.apache.shiro.crypto.hash.format.DefaultHashFormatFactory"></bean>--><!-- 缓存管理器 使用Ehcache实现<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"><property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/></bean>--><!-- 会话ID生成器--><bean id="sessionIdGenerator"class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" /><!-- 会话Cookie模板 关闭浏览器立即失效--><bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie"><constructor-arg value="sid" /><property name="httpOnly" value="true" /><property name="maxAge" value="-1" /></bean><!-- 会话DAO--><bean id="sessionDAO"class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"><property name="sessionIdGenerator" ref="sessionIdGenerator" /></bean><!-- 会话验证调度器,每30分钟执行一次验证 ,设定会话超时及保存--><bean name="sessionValidationScheduler"class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler"><property name="interval" value="1800000" /><property name="sessionManager" ref="sessionManager" /></bean><!-- 会话管理器--><bean id="sessionManager"class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"><!-- 全局会话超时时间(单位毫秒),默认30分钟--><property name="globalSessionTimeout" value="1800000" /><property name="deleteInvalidSessions" value="true" /><property name="sessionValidationSchedulerEnabled" value="true" /><property name="sessionValidationScheduler" ref="sessionValidationScheduler" /><property name="sessionDAO" ref="sessionDAO" /><property name="sessionIdCookieEnabled" value="true" /><property name="sessionIdCookie" ref="sessionIdCookie" /></bean><!-- 安全管理器 --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="userRealm" /><!-- 使用下面配置的缓存管理器 --><property name="cacheManager" ref="cacheManager" /><property name="sessionManager" ref="sessionManager" /></bean><!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) --><beanclass="org.springframework.beans.factory.config.MethodInvokingFactoryBean"><property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager" /><property name="arguments" ref="securityManager" /></bean><!-- 注册自定义的Realm,并把密码匹配器注入,使用注解的方式自动注解会无法正确匹配密码 --><bean id="userRealm" class="com.smart.shiro.UserRealm" lazy-init="false"><!--<property name="credentialsMatcher" ref="passwordMatcher"/><property name="cachingEnabled" value="false"/>--></bean><bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" /><!-- Shiro生命周期处理器 --><!-- 保证实现了Shiro内部lifecycle函数的bean执行 --><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /></beans>

SpringMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"><!--自动扫描controller--><context:component-scan base-package="com.smart.controller" /><!--开启注解--><mvc:annotation-driven /><!--视图解析--><beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix"><value>/WEB-INF/views/</value></property><property name="suffix"><value>.jsp</value></property></bean><bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 上传文件大小上限,单位为字节(10MB) --><property name="maxUploadSize"><value>10485760</value></property><!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 --><property name="defaultEncoding"><value>UTF-8</value></property></bean>
<!--Shiro配置--><!--1.配置lifecycleBeanPostProcessor,可以在Spring IOC容器中调用shiro的生命周期方法.--><bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor" id="lifecycleBeanPostProcessor" /><!--2.启用Spring IOC容器Shiro注解,但必须配置了lifecycleBeanPostProcessor后才可以使用--><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" /><!--3.开启Spring AOC Shiro注解支持--><bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager"/></bean></beans>

然后把这两个文件在web.xml中加载即可(同整合SSM时一样,无需改变),然后再添加shiro的过滤器即可

<?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_4.xsd"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_4.xsd"id="WebApp_ID" version="2.4"><!--其中在web.xml中的加载顺序为:  <context-param>(上下文) > listener > filter > servlet>interceptor--><display-name>SSM</display-name><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><!--加载配置文件--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath*:spring.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><listener><listener-class>org.springframework.web.context.ContextCleanupListener</listener-class></listener><!--字符过滤器--><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><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><!--字符过滤器--><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping> <!-- shiro 安全过滤器DelegatingFilterProxy作用是自动到spring容器查找名字为shiroFilter(filter-name)的bean并把所有Filter的操作委托给它--><filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><async-supported>true</async-supported><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-mapping><servlet-name>default</servlet-name><url-pattern>/style/*</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>/public/*</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.js</url-pattern></servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.css</url-pattern></servlet-mapping><!--Spring MVC 核心控制器DispatcherServlet--><servlet><servlet-name>spring-mvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--如果springMVC配置文件名字为spring-mvc-servlet.xml,且和web.xml在同一级目录下无需配置下面内容,否则需要配置--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath*:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>spring-mvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>

既然都写到这份上了,我就索性把所有代码都写一下

UserRealm

package com.smart.shiro;import javax.annotation.Resource;import com.smart.bean.User;
import com.smart.service.UserService;
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.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;public class UserRealm extends AuthorizingRealm {@Autowiredprivate UserService userService;@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String username = (String)principals.getPrimaryPrincipal();System.out.println(username);SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();if(userService==null){userService = SpringBeanFactoryUtils.getBean("userService");}else {System.out.println("UserRealm is not NULL");}authorizationInfo.setRoles(userService.findRoles(username));authorizationInfo.setStringPermissions(userService.findPermissions(username));return authorizationInfo;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username = (String)token.getPrincipal();System.out.println(username);if(userService==null){userService = SpringBeanFactoryUtils.getBean("userService");}else {System.out.println("UserRealmsss is not NULL");}System.out.println(username);User user = userService.findByGeNumber(username);if(user == null) {throw new UnknownAccountException();//没找到帐号}//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getGeNumber(),//用户名user.getPassword(),getName()  //realm name);return authenticationInfo;}}

View Code

Controller

@RequestMapping(value = "/UserType.do")@ResponseBodypublic Map<String,Object> Login(String geNumber, String password){System.out.println(geNumber+","+password);Map<String,Object> map = new HashMap<String,Object>();//主体,当前状态为没有认证的状态“未认证”Subject subject = SecurityUtils.getSubject();// 登录后存放进shiro tokenUsernamePasswordToken token=new UsernamePasswordToken(geNumber,password);//登录方法(认证是否通过)//使用subject调用securityManager,安全管理器调用Realmtry {//利用异常操作//需要开始调用到Realm中System.out.println("========================================");System.out.println("1、进入认证方法");subject.login(token);System.out.println("登录完成");} catch (Exception e) {map.put("tip","error");return map;}map.put("tip","success");return map;}

View Code

如果解决了你的问题,请劳驾给个推荐,谢谢!

转载于:https://www.cnblogs.com/lwx521/p/9933058.html

SSM集成shiro 致使Controller无法自动注册service相关推荐

  1. SSM集成shiro权限管理

    这几天在学习了shiro权限管理框架,在刚开始的时候学的时候因为这个配置问题困扰了我很长时间,所以在这篇文章我整合了自己用SSM搭建shiro权限框架的过程. 1.配置 1.1jar包 在项目配置开始 ...

  2. java 无法注入service_SpringBoot集成shiro,MyRealm中无法@Autowired注入Service的问题

    网上说了很多诸如是Spring加载顺序,shiroFilter在Spring自动装配bean之前的问题,其实也有可能忽略如下低级错误. 在ShiroConfiguration中要使用@Bean在App ...

  3. 基于 TS 的 React 模板项目,集成 eslint sass,采用 StandardJS 代码风格,包含自动注册组件等各项功能,新建项目或 React 学习必备

    react-typescript-sass-standard-template 项目简介 由于 Create React App 脚手架创建的项目过于简陋,没有集成诸如 eslint 等工具,致使每次 ...

  4. 在Zf2中实现Controller按照URL自动注册

    为什么80%的码农都做不了架构师?>>>    在Zf2中,一般的情况下,在modules的的某个模块的controller目录下添加一个controller 文件,对应的需要在mo ...

  5. apache shiro jar包_只需要6个步骤,springboot集成shiro,并完成登录

    小Hub领读: 导入jar包,配置yml参数,编写ShiroConfig定义DefaultWebSecurityManager,重写Realm,编写controller,编写页面,一气呵成.搞定,是个 ...

  6. spring集成shiro详解

    最近项目中要用到shiro作为权限管理,以前都是用自定义的或者spring security,所以就开始看了一些网上的文章,但是感觉都写得很零散.而且大多数都只是给了几行代码,我们得项目相对比较复杂, ...

  7. Spring Boot 极简集成 Shiro

    点击关注公众号,Java干货及时送达 1. 前言 Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理. Shiro有三大核心组件: Subject: ...

  8. SSM中shiro的基本使用

    shiro 用以网站的授权和认证 配置: 一.shiro基本配置文件 所用的entity user和role 实体类 1 @Entity 2 @Table(name="USER_P" ...

  9. SSM整合shiro权限框架

    一.SSM整合shiro框架 1.步骤 1.添加shiro框架需要的jar包,包括shiro-core.shiro-web.shiro-spring的关系依赖 <!-- shiro jar包依赖 ...

最新文章

  1. micropython中文社区 socket通讯_python网络编程学习笔记(3):socket网络服务器
  2. 人工智能简史(Rockwell Anyoha )
  3. AD属性修改 office 365 delivery management 设定
  4. OAuth 2.0协议在SAP产品中的应用
  5. 微軟平台的管理專家 - Microsoft Operations Manager (MOM)
  6. RMI和WebService
  7. 国产物联网操作系统崛起!
  8. The 2021 ICPC Asia Regionals Online Contest (I)
  9. VMPlayer Ubuntu 16.04 Copy and Paste with Host 主机与宿机之间的复制粘贴
  10. 微软商店常见的几个问题
  11. pdf格式压缩大小,pdf如何压缩大小?
  12. spellman斯派曼电源维修XRB100N100K4405
  13. msvcr71.dll文件丢失——解决办法
  14. 智慧屏如何连接电视盒子
  15. python opencv创建图像_打开国庆的正确方式,教你用OpenCV-Python轻松生成微信国庆版头像...
  16. 两分钟带你彻底明白机器学习中的过采样和欠采样是什么意思?
  17. (FZU-2285-迷宫寻宝)BFS最短路径问题
  18. 女模应聘遭遇潜规则 将计就计对面试官实施抢劫
  19. 交通大学c语言作业,交通大学C语言第二次作业说课讲解.docx
  20. Java趣谈——如何构建一个高效且可伸缩的缓存

热门文章

  1. 理发时间 2017信息学夏令营第三场
  2. 极客公园对话 Zilliz 星爵:大模型时代,需要新的「存储基建」
  3. ThinkPHP 实现QQ授权登录
  4. 安卓中关于spinner的使用
  5. Android用opencv识别红绿灯,Opencv 图像识别Android实战(识别扑克牌 8.处理筛选区)
  6. 计算机应用基础》第05章在,《计算机应用基础》第05章在线测试
  7. Windows API-GDI入门基础知识详解(转)
  8. 微信小程序--顶部状态栏切换
  9. 4.6 基于STM32+MC20地图显示路径功能
  10. 古天文表示的日月五星位置