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 }