二、加密
11. Shiro_密码的MD5加密
1.如何将一个字符串加密为MD5
2.实现将前台传递过来的密码加密,替换当前Realm的credentialsMatcher属性, 直接使用HashCredentialsMatcher对象,并设置加密算法即可。
<!--
3. 配置 Realm
3.1 直接配置实现了 org.apache.shiro.realm.Realm 接口的 bean
-->
<bean id="jdbcRealm" class="com.atguigu.shiro.realms.ShiroRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property>
<property name="hashIterations" value="1024"></property>
</bean>
</property>
</bean>
12. Shiro_密码的MD5盐值加密
本来如果两个密码是相同的那么产生的MD5密码也是一样的,为了使两个密码相同的时候所产生的密码还不一样进一步提高安全性,所以考虑添加盐值。
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
ByteSource是个接口,接口里边有Util的内部类,内部类的bytes方法
13. Shiro_多 Realm 验证
可能会出现将密码数据放在两种不同的数据库里,使用不同的加密方式。此时用户认证的时候就需要同时访问这两个数据库,就需要多个Realm,如果有多个Realm此时还涉及到认证策略的问题(有两个Realm,那怎么才算认证通过呢)。
首先,看多Realm怎么实现?
还是对login()方法级级进入,底层就会发现认证最终是通过继承的AuthenticatingRealm类中的doGetAuthenticationInfo()方法。其中分了单个与多个Realm所走的方法,并且此时这个方法在ModularRealmAuthenticator类中,所以我们要单独将它配置成一个bean,然后将这个bean配置给我们的SecurityManager。
开始搞,然后我们写SecondRealm类,其中这第二Realm使用的是SHA1加密算法(main方法中设置的参数)。
然后将这个SecondRealm配置到Spring容器中,将这两个Realm配置成一个新建的ModularRealmAuthenticator认证器,配置到SecurityManager的属性中。
1. 配置 SecurityManager!
-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<property name="authenticator" ref="authenticator"></property>
<property name="realms">
<list>
<ref bean="jdbcRealm"/>
<ref bean="secondRealm"/>
</list>
</property>
<property name="rememberMeManager.cookie.maxAge" value="10"></property>
</bean>
检验代码执行情况的办法:在判断realm个数的Collection<Realm>的那行代码处打断点,并在UsernamePassword类中的getPassword()方法上打断点,进行debug,我们就能发现此时执行的是多realm的方法,并且看到第一个realm与第二个realm所执行的算法分别是MD5和SHA1这两个不同的算法(getPassword处前几步的assertCridentialsMatch的cm属性点开就可以看到)。
14. Shiro_认证策略
源码中点入多realm执行的方法,就可以看到获取strategy和返回的认证消息aggregate。
为了看这个认证消息的效果,包含几部分的认证消息,我们可以通过在strategy和return aggregate这两行的地方打上断点来观察。首先验证默认,然后我们将认证策略改成AllSuccessfulStrategy。
我们可以在return处的断点处,的this中查看到当前的认证策略。
更改策略为AllSuccessFulStrategy的时候需要将AllSuccessFulStrategy这个bean给到哪个bean的哪个属性呢?
明确是将AllSuccessFulStrategy这个bean给到ModularRealmAuthenticator这个bean中,作为SecurityManager的属性。
<!--
1. 配置 SecurityManager!
-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<property name="authenticator" ref="authenticator"></property>
<property name="realms">
<list>
<ref bean="jdbcRealm"/>
<ref bean="secondRealm"/>
</list>
</property>
<property name="rememberMeManager.cookie.maxAge" value="10"></property>
</bean>
<!-- Let's use some enterprise caching support for better performance. You can replace this with any enterprise
caching framework implementation that you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc -->
<!--
2. 配置 CacheManager.
2.1 需要加入 ehcache 的 jar 包及配置文件.
-->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- Set a net.sf.ehcache.CacheManager instance here if you already have one. If not, a new one
will be creaed with a default config:
<property name="cacheManager" ref="ehCacheManager"/> -->
<!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you want
a specific Ehcache configuration to be used, specify that here. If you don't, a default
will be used.: -->
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>
<bean id="authenticator"
class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
<property name="authenticationStrategy">
<bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>
</property>
</bean>
15. Shiro_把 realms 配置给 SecurityManager