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 }
轉載于:https://www.cnblogs.com/dazl/p/8483552.html