您的位置:首页 > 其它

[置顶] 自学-Shiro中多Realm的配置-09

2016-12-21 12:51 281 查看
项目结构:





学习了前几节,只是知道了验证的一个流程和一些其他的原理等。

那么Realm我们该怎么去理解呢?

首先得知道Realm是什么?怎么操作?为什么要使用Realm?

①:Realm:域, Shiro 从 Realm 获取安全数据 (如用户、 角色、 权限) , 就是说 SecurityManager要验证用户身份, 那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色/权限进行验证用户是否能进行操作; 可以把 Realm 看成 DataSource , 即 安 全 数 据 源 。

②:多Realm的配置:

在创建一个java类:

youRealm.java:

package com.yiyi.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource;

public class youRealm extends AuthenticatingRealm {

@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
System.out.println("2----------->"+token);
// 将AuthenticationToken对象转换成UsernamePasswordToken对象
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
// 获取UsernamePasswordToken中的用户名
String username = upToken.getUsername();
// 从数据库中查询 username 对应的用户记录
System.out.println("从数据库中查找" + username + "的信息");
// 若用户的信息不存在,则抛出UnknownAccountException异常。
if ("unknown".equals(username)) {
throw new UnknownAccountException("用户不存在");
}
// 根据用户的信息进行反馈,则抛出LockedAccountException异常。
if ("han".equals(username)) {
throw new LockedAccountException("用户被锁定");
}
// 根据用户的信息来封装SimpleAuthenticationInfo对象。

// 当前 realm 对象的 name
String realmName = getName();
// 认证的实体信息。
Object principal = username;
// 密码
Object hashedCredentials = null;
if("admin".equals(username)){
hashedCredentials = "8a498a5ee7fe22bfdde8db4c1158f98c1fb2c2bc--";
}else if("zhao".equals(username)){
hashedCredentials = "84a31ffdbfda46f13709f4a7e69e2f1a91334c87--";
}
//盐值
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName);
return info;
}

/**
* 明文进行谜面进行加密
* @param args
*/
public static void main(String[] args) {
int hashIterations = 10000;//加密的次数
Object salt = "admin";//盐值
Object credentials = "123456";//密码
String hashAlgorithmName = "SHA1";//加密方式
Object simpleHash = new SimpleHash(hashAlgorithmName, credentials,
salt, hashIterations);
System.out.println("加密后的值----->" + simpleHash);
}

}

注意:第一个realm中采用的是MD5加密,第二个我们就采用SHA1的加密方式。配置同MD5.
那么我们该怎么去配置多个renalm呢,那么它配置的时候有没有先后顺序呢?若有先后顺序是怎么执行的呢?
applicationContext.xml:
<!--
1.securityManager:shiro 的主营业务
2.三个属性:
cacheManager:缓存用来提高性能。
sessionMode:可以先不管。
realm:Shiro 从 Realm 获取安全数据(如用户、角色、权限),就是说
SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户
进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色/
权限进行验证用户是否能进行操作。
-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<!-- Single realm app. If you have multiple realms, use the 'realms' property instead. -->
<property name="sessionMode" value="native"/>
<property name="authenticator" ref="authenticator"></property>
</bean>
<!--多个realm的配置-->
<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
<property name="realms">
<list>
<ref bean="jdbcRealm"/>
<ref bean="jdbcRealm2"/>
</list>
</property>
</bean>

<!-- 实现Realm接口即可。 -->
<bean id="jdbcRealm" class="com.yiyi.realm.MyRealm">
<!--验证方式-->
<property name="credentialsMatcher" >
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property>
<property name="hashIterations" value="10000"></property>
</bean>
</property>
</bean>

<bean id="jdbcRealm2" class="com.yiyi.realm.youRealm">
<!--验证方式-->
<property name="credentialsMatcher" >
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="SHA1"></property>
<property name="hashIterations" value="10000"></property>
</bean>
</property>
</bean>
那我们可以来验证下配置realm的有没有先后顺序以及先后顺序的执行流程。
代码如下:
<!--多个realm的配置-->
<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
<property name="realms">
<list>
<ref bean="jdbcRealm2"/>
<ref bean="jdbcRealm"/>
</list>
</property>
</bean>引用Relam的话,先进行引用第二个,再引用第一个,则在控制台可以看到打印的信息:



通过验证发现,realm配置在前面的话,先执行那个。
③:如果我们用一个项目中使用了俩种数据库,比如说mysql和Oracle,那么他们加密过的密码是不一样,所以需要配置多个realm来进行区分。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: