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/** anon13 /js/** = anon14 /images/** = anon15 /validatecode.jsp* = anon16 /login.jsp = anon17 /userAction_login.action = anon18 /page_base_staff.action = perms["staff-list"]19 /* = authc20 </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 @Override26 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 }