分享知識-快樂自己:註冊用戶密碼加密、登錄驗證及權限驗證
阿新 • • 發佈:2018-12-22
ini mission uri pwd 增加 blog 管理 sdn one
***********************以下內容僅作為參考使用:*********************************
1、用戶註冊時,將用戶設置的密碼加密後存入數據庫中(顯然密碼不能簡單地用md5加密一次或者幹脆不加密,這些都是會暴露用戶隱私的,甚至是觸動用戶的利益):
加密密碼:
//生成鹽(部分,需要存入數據庫中)
String random=new SecureRandomNumberGenerator().nextBytes().toHex();
//將原始密碼加鹽(上面生成的鹽),並且用md5算法加密三次,將最後結果存入數據庫中
String result = new Md5Hash("password",random,3).toString();
2、登錄驗證及權限驗證(繼承AuthorizingRealm,覆蓋其中的方法):
@Component
public class MyRealM extends AuthorizingRealm {
@Autowired
private LoginService loginService;
/**
* 獲取用戶角色和權限,用於權限認證
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = principals.getPrimaryPrincipal().toString();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//獲取角色(從數據庫中取出時使用逗號分隔的)
UserInfo user = loginService.getUserByName(username);
String[] roleArray = user.getUserrole().split(",");
Set<String> roles = new HashSet<String>();
for (String roleid : roleArray) {
roles.add(loginService.getRoles(roleid));
}
//獲取權限(根據角色查詢權限表)
Set<String> permissions = new HashSet<String>();
for (String roleid : roleArray) {
permissions.addAll(loginService.getPermissions(roleid));
}
info.setRoles(roles);
info.setStringPermissions(permissions);
return info;
}
/**
* 設置用戶登錄認證
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//獲取輸入的用戶賬號,並通過賬號獲取相關信息
String username = token.getPrincipal().toString();
UserInfo user = loginService.getUserByName(username);
if (user != null) {
//將查詢到的用戶賬號和密碼存放到 authenticationInfo用於後面的權限判斷。第三個參數傳入用戶輸入的用戶名。
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPwd(), getName());
//設置鹽,用來核對密碼
authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(user.getRandom()));
return authenticationInfo;
} else {
return null;
}
}
}
3、shiro增加的配置:
<!-- 配置自定義Realm,設定核對密碼時在加鹽後,要用MD5算法對用戶輸入的密碼加密3次用於核對 -->
<bean id="myRealM" class="com.test.shiro.MyRealM">
<property name="credentialsMatcher" >
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property>
<property name="hashIterations" value="3"></property>
</bean>
</property>
</bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealM"/>
</bean>
<!--Shiro過濾器-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,這個屬性是必須的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 身份認證失敗,則跳轉到登錄頁面的配置(首頁加載頁) -->
<property name="loginUrl" value="/sourceA/pageA"/>
<!--登陸成功頁面-->
<property name="successUrl" value="/list.jsp"/>
<!-- 權限認證失敗,則跳轉到指定頁面 -->
<property name="unauthorizedUrl" value="/sourceA/error"/>
<!-- Shiro連接約束配置,即過濾鏈的定義 -->
<property name="filterChainDefinitions">
<value>
<!--anon 表示匿名訪問,不需要認證以及授權 -->
/sourceB=anon
<!--authc表示需要認證,沒有進行身份認證是不能進行訪問的-->
/sourceA*=authc
<!--roles[內容] 表示需要內容所示的角色才能訪問該路徑-->
/sourceA=roles[user]
<!--perms[內容] 表示需要內容所示的權限才能訪問該路徑-->
/sourceC/**=perms["sourceC"]
/sourceD/**=authc,perms["sourceD"]
<!--除定義的可以訪問路徑以外都需要進行認證-->
/** = authc
</value>
</property>
</bean>
4、登錄,調用用戶登錄驗證(權限及角色驗證在用戶訪問某路徑時進行攔截):
//用戶信息bean
UserInfo info = new UserInfo();
info.setPwd("password");
info.setUsername("username");
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(info.getUsername(), info.getPwd());
try {
//驗證
subject.login(token);
//登陸成功後的處理邏輯:
System.out.println("登陸成功");
} catch (Exception e) {
//登陸失敗後的處理邏輯:
System.out.println("用戶名或密碼錯誤");
}
5、登出
Subject subject = SecurityUtils.getSubject();
if (subject.isAuthenticated()) {
subject.logout();
}
點我可參考其他網址:
分享知識-快樂自己:註冊用戶密碼加密、登錄驗證及權限驗證