l shiro框架的核心功能:认证、授权、会话管理、加密
Application Code:应用程序代码,由开发人员负责开发的
Subject:框架提供的接口,代表当前用户对象
SecurityManager:框架提供的接口,代表安全管理器对象
Realm:可以开发人员编写,框架也提供一些,类似于DAO,用于访问权限数据
一 、在pom中引入相关依赖
1 <!-- 引入shiro框架的依赖 --> 2 <dependency> 3 <groupId>org.apache.shiro</groupId> 4 <artifactId>shiro-all</artifactId> 5 <version>1.2.2</version> 6 </dependency>
二、在web.xml中配置spring框架提供的用于整合shiro框架的过滤器
<!-- 配置shiro框架,进行权限认证 --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
三、在spring配置文件中配置bean,id为shiroFilter
1 <!-- 配置shiro框架过滤器工厂对象 --> 2 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 3 <!-- 注入安全管理器对象 --> 4 <property name="securityManager" ref="securityManager"></property> 5 <!-- 注入相关页面的url --> 6 <property name="loginUrl" value="/login.jsp"></property> 7 <property name="successUrl" value="/index.jsp"></property> 8 <property name="unauthorizedUrl" value="/unauthorized.jsp"></property> 9 <!-- 注入url拦截规整 --> 10 <property name="filterChainDefinitions"> 11 <value> 12 /css/** anon 13 /js/** = anon 14 /images/** = anon 15 /validatecode.jsp* = anon 16 /login.jsp = anon 17 /userAction_login.action = anon 18 /page_base_staff.action = perms["staff-list"] 19 /* = authc 20 </value> 21 </property> 22 </bean>
1 <!-- 注册安全管理器对象 --> 2 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 3 <property name="realm" ref="borRealm"></property> 4 <!-- 注入缓存管理器 --> 5 <property name="cacheManager" ref="ehCacheManager"></property> 6 </bean>
<!-- 注册realm --> <bean id="borRealm" class="com.itheima.bos.realm.BOSRealm"></bean>
1 <!-- 开启shrio框架注解支持 --> 2 <bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"> 3 <!-- 强制使用cglib代理,为Action对象创建代理对象 --> 4 <property name="proxyTargetClass" value="true"></property> 5 </bean> 6 <!-- 配置shrio框架提供的切面类,用于创建代理对象 --> 7 <bean id="" class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>
1 <!-- 注册缓存管理器 --> 2 <bean id="ehCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> 3 <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"></property> 4 </bean>
四、修改login方法
1 public String login() { 2 //校验验证码是否通过 3 HttpSession session = ServletActionContext.getRequest().getSession(); 4 String key = (String) session.getAttribute("key"); 5 if(StringUtils.equals(checkcode, key)) { 6 //使用shrio框架提供的方式进行验证 7 Subject subject = SecurityUtils.getSubject();//获得当前用户对象,状态为 未认证 8 AuthenticationToken token = new UsernamePasswordToken(model.getUsername(),MD5Utils.md5(model.getPassword()));//创建用户名和密码令牌对象 9 try { 10 subject.login(token); 11 } catch (Exception e) { 12 e.printStackTrace(); 13 return LOGIN; 14 } 15 User user = (User) subject.getPrincipal(); 16 session.setAttribute("loginUser", user); 17 return HOME; 18 }else { 19 //验证码错误 20 this.addActionError("输入验证码错误"); 21 return LOGIN; 22 } 23 }
五、自定义realm,并注入给安全管理器
1 public class BOSRealm extends AuthorizingRealm { 2 @Autowired 3 private UserDao userDao; 4 @Autowired 5 private FunctionDao functionDao; 6 7 //认证 8 @Override 9 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 10 System.out.println("自定义的认证方法执行了"); 11 UsernamePasswordToken passwordToken = (UsernamePasswordToken) token; 12 //获得页面输入的用户名 13 String username = passwordToken.getUsername(); 14 //根据用户名密码查询数据库中的密码 15 User user = userDao.findUserByUsername(username); 16 if(user == null) { 17 //页面输入的用户名不存在 18 return null; 19 } 20 //简单认证信息对象 21 AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName()); 22 return info; 23 } 24 //授权 25 @Override 26 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 27 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 28 //为用户授权 29 //info.addStringPermission("staff-list"); 30 //根据当前登录用户查询数据库,获取实际对应的权限 31 User user = (User) SecurityUtils.getSubject().getPrincipal();//获取当前登录用户对象 32 //User user2 = (User) principalCollection.getPrimaryPrincipal(); 33 List<Function> list = null; 34 if(user.getUsername().equals("admin")) { 35 DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Function.class); 36 list = functionDao.findByCriteria(detachedCriteria ); 37 }else { 38 list = functionDao.findFunctionListByUserId(user.getId()); 39 } 40 for(Function function : list) { 41 info.addStringPermission(function.getCode()); 42 } 43 return info; 44 } 45 }
六、在方法上使用注解
1 //批量删除 2 @RequiresPermissions("staff-delete")//执行这个方法,需要staff-delete权限 3 public String deleteBatch() { 4 staffService.deleteBatch(ids); 5 return LIST; 6 }