shiro 框架之 加密处理。

一、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);



    }
}

五,测试。

 
 
原文地址:https://www.cnblogs.com/ZXF6/p/11346485.html