[个人记录] spring+shiro 整合
[个人记录] spring+shiro 整合
一、添加相关依赖
1 <dependency> 2 <groupId>org.apache.shiro</groupId> 3 <artifactId>shiro-core</artifactId> 4 <version>1.2.1</version> 5 </dependency> 6 <dependency> 7 <groupId>org.apache.shiro</groupId> 8 <artifactId>shiro-web</artifactId> 9 <version>1.2.1</version> 10 </dependency> 11 <dependency> 12 <groupId>org.apache.shiro</groupId> 13 <artifactId>shiro-ehcache</artifactId> 14 <version>1.2.1</version> 15 </dependency> 16 <dependency> 17 <groupId>org.apache.shiro</groupId> 18 <artifactId>shiro-spring</artifactId> 19 <version>1.2.1</version> 20 </dependency> 21 <dependency> 22 <groupId>commons-logging</groupId> 23 <artifactId>commons-logging</artifactId> 24 <version>1.2</version> 25 </dependency>
二、编写代码
1、自定义realm
1 public class CommonRealm extends AuthorizingRealm { 2 @Autowired 3 private UserLoginService userLoginService; 4 5 6 @Override 7 public String getName() { 8 return "CommonRealm"; 9 } 10 11 //授权 12 @Override 13 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 14 String usernmae = (String) principals.getPrimaryPrincipal(); 15 16 List<String> permissions = new ArrayList<String>(); 17 if ("admin".equals(usernmae)) { 18 permissions.add("admin:ee"); 19 } 20 21 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 22 info.addStringPermissions(permissions); 23 24 return info; 25 } 26 27 28 //身份认证 29 @Override 30 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 31 String username = (String) token.getPrincipal(); 32 User user = userLoginService.getUser(username); 33 if (user == null) { 34 return null; 35 } 36 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, user.getPassword(), getName()); 37 return info; 38 } 39 }
2、login controller
1 @Controller 2 public class UserAction { 3 @Autowired 4 private UserLoginService userLoginService; 5 6 @RequestMapping("/login.do") 7 public String userLogin(HttpServletRequest request, String username, String password) throws Exception { 8 // 如果登陆失败从request中获取异常信息,shiroLoginFailure就是shiro异常类的全限定名 9 String exceptionClassName = (String) request.getAttribute("shiroLoginFailure"); 10 11 if (exceptionClassName != null) { 12 if (UnknownAccountException.class.getName().equals(exceptionClassName)) { 13 // 最终会抛给异常处理器 14 throw new XXXException("用户名不存在"); 15 } else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) { 16 throw new XXXException("用户名/密码错误"); 17 } else { 18 throw new Exception();// 最终在异常处理器生成未知错误 19 } 20 } 21 22 // 如果登录成功的话不走此方法,shiro认证成功会自动跳转到上一个请求路径,配的的successUrl没效果,后边会说 23 // 登陆失败走此方法,捕获异常,然后 return ~ ,还到login页面 24 return "login.jsp"; 25 26 } 27 }
3、检测权限 controller
//此方法为了验证权限是否生效 @RequestMapping("/findAll.do") @RequiresPermissions("admin:ee") public ModelAndView list(HttpServletRequest request){ ....... }
三、常见问题
因为有一些特别常见的问题,需要修改xml配置,所以现在先手问题,把xml配置放在后边,直接就配置完善好的xml
问题一:登陆成功后shiro默认跳到上一次请求,没有上一次请求默认跳到/ ,那我们就想控制调到自己定义的路径咋办呢?
解决方案:
步骤一:继承FormAuthenticationFilter类,重写onLoginSuccess方法,这里可以自定义路径,因为这里自定义了成功跳转的路径,所以配置里的successUrl不用配置,赔了也没效果。。
1 public class LoginSuccessToFilter extends FormAuthenticationFilter { 2 @Override 3 protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception { 4 WebUtils.getAndClearSavedRequest(request); 5 WebUtils.redirectToSavedRequest(request,response,"/findAll.do"); 6 return false; 7 } 8 }
步骤二:
在shiro的xml配置文件中配置
1 <bean id=”myfilter” class=”com.xxx.realm.LoginSuccessToFilter”></bean>
在 shiroFilter配置中引入,完整xml在后边
1 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 2 <property name="filters"> 3 <map> 4 <entry key="authc" value-ref="myfilter"></entry> 5 </map> 6 </property> 7 </bean>
问题二:在controller层加 @RequiresPermissions注解不生效
解决方案: 因为controller基本都是springmvc去扫描,所以要想让加在controller层shiro注解生效,那就把配置shiro注解的配置放到mvc的配置文件中,不要放在shiro的配置中
把如下配置放入 springmvc的配置文件中。
<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>
四、Xml配置
applicationContext-shiro.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee" 6 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 9 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd 10 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 11 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> 12 13 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 14 <!-- 管理器,必须设置 --> 15 <property name="securityManager" ref="securityManager"/> 16 17 <property name="filters"> 18 <map> 19 <entry key="authc" value-ref="myfilter"></entry> 20 </map> 21 </property> 22 23 <!-- 拦截到,跳转到的地址,通过此地址去认证 --> 24 <property name="loginUrl" value="/login.do"/> 25 <!-- 认证成功统一跳转到/admin/index.do,建议不配置,shiro认证成功自动到上一个请求路径 --> 26 <!--<property name="successUrl" value="/findAll.do"/>--> 27 <!-- 通过unauthorizedUrl指定没有权限操作时跳转页面 --> 28 <property name="unauthorizedUrl" value="/refuse.jsp"/> 29 <!-- 自定义filter,可用来更改默认的表单名称配置 --> 30 <!--<property name="filters">--> 31 <!--<map>--> 32 <!--<!– 将自定义 的FormAuthenticationFilter注入shiroFilter中 –>--> 33 <!--<entry key="authc" value-ref="formAuthenticationFilter" />--> 34 <!--</map>--> 35 <!--</property>--> 36 <property name="filterChainDefinitions"> 37 <value> 38 <!-- 对静态资源设置匿名访问 --> 39 /image/** = anon 40 /css/** = anon 41 /js/** = anon 42 /logout.do = logout 43 /** = authc 44 </value> 45 </property> 46 </bean> 47 48 <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> 49 50 51 <!-- securityManager安全管理器 --> 52 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 53 <property name="realm" ref="customRealm"/> 54 <!-- 注入缓存管理器 --> 55 <!--<property name="cacheManager" ref="cacheManager" />--> 56 <!-- 注入session管理器 --> 57 <!-- <property name="sessionManager" ref="sessionManager" /> --> 58 <!-- 记住我 --> 59 <!--<property name="rememberMeManager" ref="rememberMeManager" />--> 60 </bean> 61 62 <!-- 自定义realm --> 63 <bean id="customRealm" class="com.dhl.realm.CommonRealm"></bean> 64 65 <bean id="myfilter" class="com.dhl.realm.LoginSuccessToFilter"></bean> 66 67 <!-- 凭证匹配器 --> 68 <!--<bean id="credentialsMatcher"--> 69 <!--class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">--> 70 <!--<!– 选用MD5散列算法 –>--> 71 <!--<property name="hashAlgorithmName" value="md5"/>--> 72 <!--<!– 进行一次加密 –>--> 73 <!--<property name="hashIterations" value="1"/>--> 74 <!--</bean>--> 75 76 77 78 79 80 </beans>
springmvc的配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:jdbc="http://www.springframework.org/schema/jdbc" 8 xsi:schemaLocation="http://www.springframework.org/schema/beans 9 http://www.springframework.org/schema/beans/spring-beans.xsd 10 http://www.springframework.org/schema/aop 11 http://www.springframework.org/schema/aop/spring-aop.xsd 12 http://www.springframework.org/schema/tx 13 http://www.springframework.org/schema/tx/spring-tx.xsd 14 http://www.springframework.org/schema/context 15 http://www.springframework.org/schema/context/spring-context.xsd 16 http://www.springframework.org/schema/mvc 17 http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd"> 18 19 20 <context:component-scan base-package="com.dhl.controller"></context:component-scan> 21 <mvc:annotation-driven></mvc:annotation-driven> 22 23 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean> 24 25 <!-- 开启shiro注解的配置移动到这儿 --> 26 <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> 27 <property name="proxyTargetClass" value="true" /> 28 </bean> 29 <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> 30 <property name="securityManager" ref="securityManager"/> 31 </bean> 32 33 34 </beans>
以上就是一个大概的整合和遇到的两个问题,博主也是查阅了很多的博客得到的较优答案,整理出来,已备后续参考,遇到一样问题的同学可以看看
侵删致歉