ssm整合shiro框架,對用戶的登錄操作進行認證和授權,目的很純粹就是為了增加系統的安全線,至少不要輸在門檻上嘛。
這幾天在公司獨立開發一個供公司內部人員使用的小管理系統,客戶不多但是登錄一直都是簡單的校驗查詢,沒有使用任何安全框架來保駕護航,下午終於拿出以前的手段來完善了一下,將shiro安全框架與ssm整合使用的步驟和大家分享一下,都是些簡單易懂的東西,希望努力沒有白費,幫到大家。
ssm整合shiro安全框架的步驟:
1、引入shiro安全框架的所需jar包
1 <!-- shiro --> 2 <dependency> 3 <groupId>org.apache.shiro</groupId> 4 <artifactId>shiro-core</artifactId> 5 <version>1.2.3</version> 6 </dependency> 7 <dependency> 8 <groupId>org.apache.shiro</groupId> 9 <artifactId>shiro-spring</artifactId> 10 <version>1.2.3</version> 11 </dependency> 12 <dependency> 13 <groupId>org.apache.shiro</groupId> 14 <artifactId>shiro-web</artifactId> 15 <version>1.2.3</version> 16 </dependency> 17 <dependency> 18 <groupId>org.apache.shiro</groupId> 19 <artifactId>shiro-ehcache</artifactId> 20 <version>1.2.3</version> 21 </dependency>
2、在web.xml文件中配置shiro攔截器
1 <!-- spring整合安全框架 --> 2 <filter> 3 <filter-name>DelegatingFilterProxy</filter-name> 4 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 5 <!-- 初始化參數 --> 6 <init-param> 7 <param-name>targetBeanName</param-name> 8 <param-value>shiroFilter</param-value> 9 </init-param> 10 </filter> 11 <filter-mapping> 12 <filter-name>DelegatingFilterProxy</filter-name> 13 <url-pattern>/*</url-pattern> 14 </filter-mapping>
3、創建spring整合shiro安全框架的配置文件applicationContext-shiro.xml(各位在拷貝的時候記得修改一下跳轉連接地址)
1 <!-- shiro開啟事務注解 --> 2 <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> 3 <property name="securityManager" ref="securityManager" /> 4 </bean> 5 6 <!-- 7 /** 除了已經設置的其他路徑的認證 8 --> 9 <!-- shiro工廠bean配置 --> 10 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 11 <!-- shiro的核心安全接口 --> 12 <property name="securityManager" ref="securityManager"></property> 13 <!-- 要求登錄時的連接 --> 14 <property name="loginUrl" value="/login.jsp"></property> 15 <!-- 登錄成功后要跳轉的連接(此處已經在登錄中處理了) --> 16 <!-- <property name="successUrl" value="/index.jsp"></property> --> 17 <!-- 未認證時要跳轉的連接 --> 18 <property name="unauthorizedUrl" value="/refuse.jsp"></property> 19 <!-- shiro連接約束配置 --> 20 <property name="filterChainDefinitions"> 21 <value> 22 <!-- 對靜態資源設置允許匿名訪問 --> 23 /images/** = anon 24 /js/** = anon 25 /css/** = anon 26 <!-- 可匿名訪問路徑,例如:驗證碼、登錄連接、退出連接等 --> 27 /auth/login = anon 28 <!-- 剩余其他路徑,必須認證通過才可以訪問 --> 29 /** = authc 30 </value> 31 </property> 32 </bean> 33 34 <!-- 配置shiro安全管理器 --> 35 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 36 <property name="realms" ref="customRealm"></property> 37 </bean> 38 39 <!-- 自定義Realm --> 40 <bean id="customRealm" class="com.zxz.auth.realm.UserRealm"> 41 <property name="credentialsMatcher" ref="credentialsMatcher"></property> 42 </bean> 43 44 <!-- 配置憑證算法匹配器 --> 45 <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> 46 <!-- Md5算法 --> 47 <property name="hashAlgorithmName" value="Md5"></property> 48 </bean>
【高能說明:以上倆個配置文件中加粗畫線的紅色部分必須一致,沒毛病。】
還需要說明的是,在上面的配置文件中shiro連接約束配置那塊,要特別小心,哥們我就在哪塊吃了2天的折磨虧,當時是只配置了/** = authc,沒有配置可匿名訪問的路徑,當時是什么情況吧,就是無限次的調試無限次的修改,我是真長記性了,還有一點就是在配置的時候把你項目中的靜態資源放開,被屏蔽了啊,好心提醒,不謝。
4、當然,在這之前,還要編寫自定義realm類,該類必須認AuthorizingRealm類做爸爸,不然你是不行滴,之后還有倆個兒子需要處理了,一個是認證另一個授權,理論我就不多說了,MD沒用。
1 public class UserRealm extends AuthorizingRealm { 2 3 @Autowired 4 private UserService userService; 5 6 @Override 7 public String getName() { 8 return "customRealm"; 9 } 10 11 /** 12 * 認證 13 */ 14 @Override 15 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 16 // 獲取用戶名稱 17 String username = (String) token.getPrincipal(); 18 User user = userService.findByUsername(username); 19 if (user == null) { 20 // 用戶名不存在拋出異常 21 System.out.println("認證:當前登錄的用戶不存在"); 22 throw new UnknownAccountException(); 23 } 24 String pwd = user.getPassword(); 25 return new SimpleAuthenticationInfo(user, pwd, getName()); 26 } 27 28 /** 29 * 授權 30 */ 31 @Override 32 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection princ) { 33 return null; 34 } 35 }
5、到這兒,shiro安全框架的整合是完成了,然后編寫action類來實現登錄功能,不多說了,直接上代碼。
1 /** 2 * shiro框架登錄 3 * @param user 4 */ 5 @RequestMapping(value = "/login",method=RequestMethod.POST) 6 public ModelAndView login(User user){ 7 // 表面校驗 8 if(!StringUtil.isNullOrBlank(user.getUsername()) || !StringUtil.isNullOrBlank(user.getPassword())){ 9 return new ModelAndView("login") 10 .addObject("message", "賬號或密碼不能為空") 11 .addObject("failuser", user); 12 } 13 // 獲取主體 14 Subject subject = SecurityUtils.getSubject(); 15 try{ 16 // 調用安全認證框架的登錄方法 17 subject.login(new UsernamePasswordToken(user.getUsername(), user.getPassword())); 18 }catch(AuthenticationException ex){ 19 System.out.println("登陸失敗: " + ex.getMessage()); 20 return new ModelAndView("login") 21 .addObject("message", "用戶不存在") 22 .addObject("failuser", user); 23 } 24 // 登錄成功后重定向到首頁 25 return new ModelAndView("redirect:/index"); 26 }
最后需要給大家說的就是,當某用戶登錄成功之后,shiro安全框架就會將用戶的信息存放在session中,你可以通過User user = (User) SecurityUtils.getSubject().getPrincipal();這句代碼在任何地方任何時候都能獲取當前登錄成功的用戶信息。
很長年間沒用shiro安全框架了,原理忘得都差不多了,但是駕馭它還是沒問題的,如果哪兒寫的不對的,希望各位指教,盡管我脾氣很爆,哈哈哈。