一、shiro 加密?
/* Shiro? 一、為什么要加密? 為調高數據庫的安全性,需要給密碼加密。 二、常見的加密算法? 1.1哈希算法 md5:加密算法 哈希函數 1.2.對稱算法 1.3.非對稱算法 三、如何進行加密后的匹配? 注冊用戶-----獲取用戶對象----密碼加密---存數據庫 四.如何匹配? 對密碼先加密----匹配 token :前台穿過來的密碼(未加密) join:數據庫中已經加密的密碼 */
二、實現。
在shiro.xml中1.開啟密碼匹配器
2.logout 注銷 設置一個注銷的方法,可以清除session中緩存。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--1.安全管理器--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--緩存管理器 暫時不引用他--> <!--<property name="cacheManager" ref="cacheManager"/>--> <!--會話的模式--> <property name="sessionMode" value="native"/> <!--配置realm --> <property name="realm" ref="myRealm"/> </bean> <!--2.緩存管理器--> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> </bean> <bean id="myRealm" class="com.aaa.realm.MyRealm"> <property name="name" value="myRealm"/> <!--3.品證(密碼)匹配器--> <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <!--加密算法的名稱 --> <property name="hashAlgorithmName" value="MD5"/> <!-- 是否讓它 進行16進制的編碼 --> <property name="storedCredentialsHexEncoded" value="true"/> <!-- 迭代的次數 123。。。。加密 。。。。加密 1024 次 叫做迭代。 --> <!--<property name="hashIterations" value="1024"/>--> </bean> </property> </bean> <!--4.shiro中的類型要交給 spring容器管理的bean--> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!--5.啟用注解配置--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean> <!-- 6. shiro 的過濾器 id和名字保持一致 和web.xml 中過濾器的名字保持一致。否則配置沒有效果。 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!--1.引入安全管理器 --> <property name="securityManager" ref="securityManager"/> <!--2.登錄的地址 --> <property name="loginUrl" value="/login.jsp"/> <!--3.登錄成功的頁面 --> <property name="successUrl" value="/index.jsp"/> <!--4.綁定一個未授權的路徑。--> <property name="unauthorizedUrl" value="/unauthorized.jsp"/> <!-- <property name="filters"> <util:map> <entry key="aName" value-ref="someFilterPojo"/> </util:map> filterChainDefinitions 過濾器的規則聲明。 1.anon 匿名不需要驗證 2. authc 認證 需要登錄 3.perms 權限 4.logout 注銷 設置一個注銷的方法,可以清楚session中緩存。 /admin/** = authc 下的路徑都需要進行登錄認證 從上到下 前面規定好的 沖突就是優先級。 </property> --> <property name="filterChainDefinitions"> <value> /login.jsp = anon /index.jsp = anon /static/** =anon /logout=logout # allow WebStart to pull the jars for the swing app: /*.jar = anon # everything else requires authentication: /dept/**=authc /admin/** = authc </value> </property> </bean> </beans>
3.index.jsp 添加注銷的超鏈連。
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2019/8/5 Time: 10:04 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>mvc</title> </head> <body> <a href="view/addcaidan.jsp">菜單錄入</a><br> <a href="admin/empdemo.jsp">admin路徑下的 員工管理的查詢 錄入 刪除</a><br> <a href="admin/empdemo1.jsp">admin路徑下的 員工系統的增刪改查</a><br> <a href="admin/wenjianshangchuang.jsp">admin路徑下的 通過表單上傳數據</a><br> <a href="view/wenjiango.jsp"> 單個文件</a><br> <a href="login.jsp"> 登錄驗證測試</a><br> <a href="view/duowenjian.jsp"> 多文件上傳</a><br> <%-- 在shiro中配置一個注銷的設置 在首頁直接點擊注銷 就能注銷session--%> <a href="logout">注銷</a><br> </body> </html>
三、簡單的加密方式?
2.1token 前台傳過來的密碼是沒有加密的,通過shiro去加密,然后再匹配。
2.2info 中的原始密碼,通過加密的方式,加密,得到一列字符串
2.3 在這里 我只對密碼進行了限制是 666 ,用戶名,可以隨便輸入
package com.aaa.realm; import org.apache.shiro.authc.*; import org.apache.shiro.crypto.hash.SimpleHash; import org.apache.shiro.realm.AuthenticatingRealm; import org.apache.shiro.util.ByteSource; /*1.編碼實現realm類 * 2.繼承AuthenticatingRealm * * 3.返回一個實現類 驗證交給shiro * * realm * * 1.獲取subject傳遞過來的token * 2.根據token中的用戶名,找到密碼 * 3.返回認證的對象。 * */ public class MyRealm extends AuthenticatingRealm { @Override //令牌信息 從表單中傳遞過來的身份信息 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken) authenticationToken; //獲取令牌中的用戶名 String username = usernamePasswordToken.getUsername(); //連接數據庫 進行查詢操作 根據用戶名 查詢密碼 模擬密碼 // String password="666"; String password="fae0b27c451c728867a567e8c1bb4e53"; //數據庫中加密后的密碼 模擬獲取 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,password,getName()); return info; } public static void main(String[] args) { // String username="admin"; // String password="123"; //算法的名稱 和 原始密碼 SimpleHash simpleHash = new SimpleHash("MD5","666" ); //得到 加密后的數據 fae0b27c451c728867a567e8c1bb4e53 String s = simpleHash.toHex(); System.out.println(s); } }
四。增添鹽值 salt ,根據名字進行加密。
為什么?
在數據庫中,不同的用戶,可能存在相同的密碼,這也是不安全的。---------》salt解決問題。
package com.aaa.realm; import com.aaa.util.MD5Utils; import org.apache.shiro.authc.*; import org.apache.shiro.crypto.hash.SimpleHash; import org.apache.shiro.realm.AuthenticatingRealm; import org.apache.shiro.util.ByteSource; public class MyRealm extends AuthenticatingRealm { @Override //令牌信息 從表單中傳遞過來的身份信息 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken) authenticationToken; //獲取令牌中的用戶名 String username = usernamePasswordToken.getUsername(); String password="0668410aa0944d32908ca1fd66890c92"; //數據庫中加密的密碼 // 1.這里也要加上鹽值 和下面匹配。 2.用戶名充當鹽值,不固定,不要把用戶名寫死。 username代替。 ByteSource salt = ByteSource.Util.bytes(username); //返回認證信息 添加一個 密碼加密 salt 用戶名 散列的密碼 鹽值,用戶名 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,password,salt,getName()); return info; } public static void main(String[] args) { //模擬數據庫中的一個用戶名 String username="haha"; //加鹽,salt 類型是ByteSource 解決不同用戶名密碼相同的問題。 ByteSource salt = ByteSource.Util.bytes("haha"); //算法的名稱 和 原始密碼 鹽值 SimpleHash simpleHash = new SimpleHash("MD5","666" ,salt); //得到 加密后的數據 0668410aa0944d32908ca1fd66890c92 String s = simpleHash.toHex(); System.out.println(s); } }
五,測試。