SpringMVC整合Shiro
来源:互联网 发布:highcharts无数据显示 编辑:程序博客网 时间:2024/05/16 10:55
第一步:配置web.xml
<!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 --> <!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter"/> --> <!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 --> <!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的 --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 --> <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>
第二步:在applicationContext.xml中引入shiro.xml一句话:<import resource="shiro.xml" />
第三步:配置shiro.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:mybatis="http://www.mybatis.org/schema/mybatis" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task" 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.mybatis.org/schema/mybatis http://www.mybatis.org/schema/mybatis/mybatis-spring.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> <!-- 会话管理器 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!-- <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="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" /> <!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的ShiroDbRealm.java --> <bean id="myRealm" class="com.zxzl.service.web.util.MyRealm"/> <!-- Shiro默认会使用Servlet容器的Session,可通过sessionMode属性来指定使用Shiro原生Session --> <!-- 即<property name="sessionMode" value="native"/>,详细说明见官方文档 --> <!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm" /> <!-- <property name="cacheManager" ref="cacheManager"/> --> <!-- <property name="sessionManager" ref="sessionManager"/> --> </bean> <!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 --> <!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- Shiro的核心安全接口,这个属性是必须的 --> <property name="securityManager" ref="securityManager" /> <!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面 --> <property name="loginUrl" value="/login" /> <!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码为main.jsp了) --><!-- <property name="successUrl" value="/loginSuccess"/> --> <!-- 用户访问未对其授权的资源时,所显示的连接 --> <!-- 若想更明显的测试此属性可以修改它的值,如unauthor.jsp,然后用[玄玉]登录后访问/admin/listUser.jsp就看见浏览器会显示unauthor.jsp --> <property name="unauthorizedUrl" value="/unauth" /> <!-- Shiro连接约束配置,即过滤链的定义 --> <!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath()的值来的 --> <!-- anon:它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 --> <!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter --> <property name="filterChainDefinitions"><value> <!-- /assets/** = anon --><!-- /style/** = anon --><!-- /images/** = anon --><!-- /javascript/** = anon --><!-- /layer/** = anon --><!-- /res/** =anon --> /**= anon </value></property> </bean> </beans>
第四步:自定义的Realm类
package com.zxzl.service.web.util;import java.util.List;import javax.annotation.Resource;import org.apache.shiro.SecurityUtils;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.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.session.Session;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.Subject;import com.zxzl.service.common.framework.util.MobileUtil;import com.zxzl.service.web.beans.SysUser;import com.zxzl.service.web.beans.SysUserExample;import com.zxzl.service.web.service.SysUserService;/** * * <p>Title:MyRealm </p>* <p>Description:定义自己的认证授权器 </p>* <p>Company: </p> * @author WANGZG* @date 2016年10月27日上午11:04:28 */public class MyRealm extends AuthorizingRealm { /** * @Fields sysUserService : TODO[注入系统用户服务接口对象] */ @Resource private SysUserService sysUserService; /** * 为当前登录的Subject授予角色和权限 * @see 经测试:本例中该方法的调用时机为需授权资源被访问时 * @see 经测试:并且每次访问需授权资源时都会执行该方法中的逻辑,这表明本例中默认并未启用AuthorizationCache * @see 个人感觉若使用了Spring3.1开始提供的ConcurrentMapCache支持,则可灵活决定是否启用AuthorizationCache * @see 比如说这里从数据库获取权限信息时,先去访问Spring3.1提供的缓存,而不使用Shior提供的AuthorizationCache */ @Override public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){ //获取当前登录的用户名,等价于(String)principals.fromRealm(this.getName()).iterator().next() String currentUsername = (String)super.getAvailablePrincipal(principals); // List<String> roleList = new ArrayList<String>(); // List<String> permissionList = new ArrayList<String>(); // //从数据库中获取当前登录用户的详细信息 // User user = userService.getByUsername(currentUsername); // if(null != user){ // //实体类User中包含有用户角色的实体类信息 // if(null!=user.getRoles() && user.getRoles().size()>0){ // //获取当前登录用户的角色 // for(Role role : user.getRoles()){ // roleList.add(role.getName()); // //实体类Role中包含有角色权限的实体类信息 // if(null!=role.getPermissions() && role.getPermissions().size()>0){ // //获取权限 // for(Permission pmss : role.getPermissions()){ // if(!StringUtils.isEmpty(pmss.getPermission())){ // permissionList.add(pmss.getPermission()); // } // } // } // } // } // }else{ // throw new AuthorizationException(); // } // //为当前用户设置角色和权限 // SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo(); // simpleAuthorInfo.addRoles(roleList); // simpleAuthorInfo.addStringPermissions(permissionList); SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo(); //实际中可能会像上面注释的那样从数据库取得 if(null!=currentUsername && "admin".equals(currentUsername)){ //添加一个角色,不是配置意义上的添加,而是证明该用户拥有admin角色 simpleAuthorInfo.addRole("admin"); //添加权限 simpleAuthorInfo.addStringPermission("admin:manage"); System.out.println("已为用户[admin]赋予了[admin]角色和[admin:manage]权限"); return simpleAuthorInfo; } //若该方法什么都不做直接返回null的话,就会导致任何用户访问/admin/listUser.jsp时都会自动跳转到unauthorizedUrl指定的地址 //详见applicationContext.xml中的<bean id="shiroFilter">的配置 return null; } /** * 验证当前登录的Subject * @see 经测试:本例中该方法的调用时机为LoginController.login()方法中执行Subject.login()时 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { //获取基于用户名和密码的令牌 //实际上这个authcToken是从LoginController里面currentUser.login(token)传过来的 //两个token的引用都是一样的 UsernamePasswordToken token = (UsernamePasswordToken)authcToken; SysUserExample example = new SysUserExample(); SysUserExample.Criteria criteria = example.createCriteria(); criteria.andLoginIdEqualTo(token.getUsername()); criteria.andPasswordEqualTo(String.valueOf(token.getPassword())); List<SysUser> userList = sysUserService.selectByExample(example); if(null != userList && userList.size()!=0){ SysUser sysUser = userList.get(0); AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(sysUser.getLoginId(), sysUser.getPassword(),sysUser.getNickname()); this.setSession("sysUser", sysUser); return authcInfo; }else{ return null; } } /** * 将一些数据放到ShiroSession中,以便于其它地方使用 * @see 比如Controller,使用时直接用HttpSession.getAttribute(key)就可以取到 */ private void setSession(Object key, Object value){ Subject currentUser = SecurityUtils.getSubject(); if(null != currentUser){ Session session = currentUser.getSession(); System.out.println("Session默认超时时间为[" + session.getTimeout() + "]毫秒"); if(null != session){ session.setAttribute(key, value); } } }}第五步 controller类package com.zxzl.service.web.controller;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.servlet.ModelAndView;import com.zxzl.service.common.framework.base.BaseController;import com.zxzl.service.common.framework.util.MobileUtil;import com.zxzl.service.web.service.SysResService;import com.zxzl.service.web.util.CommTool;import com.zxzl.service.web.util.Const;@Controller("WebLoginController")@RequestMapping(value = "/")public class WebLoginController extends BaseController { @Autowired private SysResService sysResService; /** * 判断用户是否登录 * * @param currUser * @return */ @RequestMapping(value = "/authority/login") public ModelAndView login(@RequestParam(value = "userName", required = true) String userName, @RequestParam(value = "userPass", required = true) String userPass) { Subject user = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(userName,MobileUtil.getMD5Pass(String.valueOf(userPass))); token.setRememberMe(true); ModelAndView mv= new ModelAndView(); try { user.login(token); Map<String, Object> params = new HashMap<String, Object>(); params.put(Const.SQLNAME, "select2001"); List<Map<String, Object>> list = sysResService.selectRes(params); Map<String, List<Map<String, Object>>> menuMap = new HashMap<String, List<Map<String, Object>>>(); String parentNode = null; for (Map<String, Object> map : list) { parentNode = map.get("pNode").toString(); if (CommTool.checkMapEmpty(menuMap, parentNode)) { menuMap.get(parentNode).add(map); } else { List<Map<String, Object>> tempList = new ArrayList<Map<String, Object>>(); tempList.add(map); menuMap.put(parentNode, tempList); } } mv.addObject("menuMap", menuMap); mv.setViewName("admin/index"); }catch (AuthenticationException e) { //log.error("登录失败错误信息:"+e); System.out.println(e.getStackTrace()); e.getStackTrace(); mv.setViewName("redirect:/login.jsp?errMsg=1"); token.clear(); } return mv; } }第六步 补充要是使用maven管里项目需要引入shiro相关JAR包<!-- shiro核心接口 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.4</version> </dependency>
0 0
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- springmvc整合shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- Springmvc整合shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- log4j自带的两个类MDC和NDC作用以及用途
- 前端开发涉及的知识点
- ELK 搭建
- UEFI\BIOS 开坑, 立flag
- Android 小項目之--RadionButton 和RadionGroup應用
- SpringMVC整合Shiro
- oclhashcat:离线hash密码破解工具官方文档(中文版)
- css3 flex 布局理解
- 390. Elimination Game
- 磁珠的选型规范
- Android 获取 TextView 显示的字符串宽度
- JavaWeb监听器
- springmvc+maven框架介绍
- 香港手机号、固话、身份证正则表达式校验