shiro實踐(1):注冊用戶密碼加密、登錄驗證及權限驗證


shiro是java的安全框架,能方便地實現項目的身份驗證、權限驗證等相關安全方面的功能。本人用的shiro版本是1.2.3的,當然還是推薦高版本的,功能封裝得更完善些。

 

1.用戶注冊時,將用戶設置的密碼加密后存入數據庫中(顯然密碼不能簡單地用md5加密一次或者干脆不加密,這些都是會暴露用戶隱私的,甚至是觸動用戶的利益):

 

1         //生成鹽(部分,需要存入數據庫中)
2         String random=new SecureRandomNumberGenerator().nextBytes().toHex();
3         
4         //將原始密碼加鹽(上面生成的鹽),並且用md5算法加密三次,將最后結果存入數據庫中
5         String result = new Md5Hash("password",random,3).toString();

 

2.登錄驗證及權限驗證(繼承AuthorizingRealm,覆蓋其中的方法):

 1 @Component
 2 public class MyRealM extends AuthorizingRealm {
 3 
 4 
 5     @Autowired
 6     private LoginService loginService;
 7 
 8     /**
 9      * 獲取用戶角色和權限,用於權限認證
10      * @param principals
11      * @return
12      */
13     @Override
14     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
15 
16         String username = principals.getPrimaryPrincipal().toString();
17 
18         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
19         //獲取角色(從數據庫中取出時使用逗號分隔的)
20         UserInfo user = loginService.getUserByName(username);
21         String[] roleArray = user.getUserrole().split(",");
22 
23         Set<String> roles = new HashSet<String>();
24         for (String roleid : roleArray) {
25             roles.add(loginService.getRoles(roleid));
26         }
27 
28         //獲取權限(根據角色查詢權限表)
29         Set<String> permissions = new HashSet<String>();
30         for (String roleid : roleArray) {
31             permissions.addAll(loginService.getPermissions(roleid));
32         }
33 
34         info.setRoles(roles);
35         info.setStringPermissions(permissions);
36         return info;
37     }
38 
39     /**
40      * 設置用戶登錄認證
41      * @param token
42      * @return
43      * @throws AuthenticationException
44      */
45     @Override
46     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
47         //獲取輸入的用戶賬號,並通過賬號獲取相關信息
48         String username = token.getPrincipal().toString();
49         UserInfo user = loginService.getUserByName(username);
50         if (user != null) {
51             //將查詢到的用戶賬號和密碼存放到 authenticationInfo用於后面的權限判斷。第三個參數傳入用戶輸入的用戶名。
52             SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPwd(), getName());
53             //設置鹽,用來核對密碼
54             authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(user.getRandom()));
55           
56             return authenticationInfo;
57         } else {
58             return null;
59         }
60 
61     }
62 
63 
64 }

 

3.shiro增加的配置:

 1     <!-- 配置自定義Realm,設定核對密碼時在加鹽后,要用MD5算法對用戶輸入的密碼加密3次用於核對 -->
 2     <bean id="myRealM" class="com.test.shiro.MyRealM">
 3         <property name="credentialsMatcher" >
 4             <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
 5                 <property name="hashAlgorithmName" value="MD5"></property>
 6                 <property name="hashIterations" value="3"></property>
 7             </bean>
 8         </property>
 9     </bean>
10 
11 
12     <!-- 安全管理器 -->
13     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
14         <property name="realm" ref="myRealM"/>
15     </bean>
16 
17     <!--Shiro過濾器-->
18     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
19         <!-- Shiro的核心安全接口,這個屬性是必須的 -->
20         <property name="securityManager" ref="securityManager"/>
21         <!-- 身份認證失敗,則跳轉到登錄頁面的配置 -->
22         <property name="loginUrl" value="/sourceA/pageA"/>
23         <!-- 權限認證失敗,則跳轉到指定頁面 -->
24         <property name="unauthorizedUrl" value="/sourceA/error"/>
25         <!-- Shiro連接約束配置,即過濾鏈的定義 -->
26         <property name="filterChainDefinitions">
27             <value>
28                  <!--anon 表示匿名訪問,不需要認證以及授權 -->
29                 /sourceB=anon
30                  <!--authc表示需要認證,沒有進行身份認證是不能進行訪問的-->
31                 /sourceA*=authc
32                  <!--roles[內容] 表示需要內容所示的角色才能訪問該路徑-->
33                 /sourceA=roles[user]
34                  <!--perms[內容] 表示需要內容所示的權限才能訪問該路徑-->
35                 /sourceC/**=perms["sourceC"]
36                 /sourceD/**=authc,perms["sourceD"]
37            
38             </value>
39         </property>
40     </bean>

 

 

4.登錄,調用用戶登錄驗證(權限及角色驗證在用戶訪問某路徑時進行攔截):

 1         //用戶信息bean      
 2         UserInfo info = new UserInfo();
 3         info.setPwd("password");
 4         info.setUsername("username");
 5 
 6         Subject subject = SecurityUtils.getSubject();
 7         UsernamePasswordToken token = new UsernamePasswordToken(info.getUsername(), info.getPwd());
 8 
 9         try {
10 
11             //驗證
12             subject.login(token);
13            
14             //登陸成功后的處理邏輯:      
15             System.out.println("登陸成功");
16            
17         } catch (Exception e) {
18             //登陸失敗后的處理邏輯:
19             System.out.println("用戶名或密碼錯誤");
20            
21         }

 

5.登出

1   Subject subject = SecurityUtils.getSubject();
2         if (subject.isAuthenticated()) {
3             subject.logout();
4         }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM