shrio--------(4)散列加密,自定义realm的实现

1、shrio自带提供多种加密的方法:

散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5、SHA等。一般进行散列时最好提供一个salt(盐),比如加密密码“admin”,产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,可以到一些md5 解密网站很容易的通过散列值得到密码“admin”,即如果直接对密码进行散列相对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,如用户名和ID(即盐);这样散列的对象是“密码+用户名+ID”,这样生成的散列值相对来说更难破解

 

2、加密的使用代码

public class ShiroTest {
	//shiro提供了现成的加密类  Md5Hash
	@Test
	public void testMd5(){
		//MD5加密
		String password = new Md5Hash("1111").toString();
		System.out.println("加密后:"+password);
		//加盐  salt  默认一次散列
		String password_salt=new Md5Hash("1111", "siggy").toString();
		System.out.println("加盐后:"+password_salt);
		//散列2次
		String password_salt_2 = new Md5Hash("1111", "siggy", 2).toString();
		System.out.println("散列2次:"+password_salt_2);
		//使用SimpleHash
		SimpleHash hash = new SimpleHash("MD5", "1111", "siggy", 2);
		System.out.println("simpleHash:"+hash.toString());
	}
}

 

3、自定义realm的实现课加密的

 3.1带入相关的maven依赖

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.25</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>0.2.23</version>
        </dependency>
    </dependencies>

3.2 继承AuthorizingRealm,写自己的realm

public class MyRealm extends AuthorizingRealm {

    @Override
    public String getName() {
        return "myRealm";
    }

    /**
     * 身份检验
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        /**
         * 获取用户名
         */
        String username = (String)authenticationToken.getPrincipal();
        /**
         * 假设通过用户名从数据库获取用户密码
         */
        String password = "78a5940ee29370a687489906a35abb2c";
        String salt = "stx";

        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,password, ByteSource.Util.bytes(salt),getName());
        return simpleAuthenticationInfo;
    }


    /**
     * 授权
     * @param principalCollection
     * @return
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        /**
         * 获取用户名
         */
        String username =(String)principalCollection.getPrimaryPrincipal();

        /**
         * 获取该用户对应的权限
         */
        List<String> listRole = new ArrayList<String>();
        listRole.add("user");
        listRole.add("admin");

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        for (String role:listRole) {
            authorizationInfo.addRole(role);
        }


        List<String> listPermssion = new ArrayList<String>();
        listPermssion.add("user:add");
        listPermssion.add("user:update");
        for (String permssion:listPermssion) {
            authorizationInfo.addStringPermission(permssion);
        }
        return authorizationInfo;
    }

}
3.3配置ini文件
[main]
#配置凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher
credentialsMatcher.hashAlgorithmName=md5
credentialsMatcher.hashIterations=2

#配置自定义的realm
myRealm=com.feng.realm.MyRealm
myRealm.credentialsMatcher=$credentialsMatcher

#配置securityManager
securityManager=org.apache.shiro.mgt.DefaultSecurityManager
securityManager.realms=$myRealm

 

3.4写代码进行测试

public static void main(String args[]){
        //1、创建工厂
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shrio.ini");
        //2、通过工厂创建SercurityManager
        SecurityManager securityManager = factory.getInstance();
        //3、将SecurityManager设置进入SecurityUtils
        SecurityUtils.setSecurityManager(securityManager);
        //4、从SecurityUtils获取主体Subject
        Subject subject = SecurityUtils.getSubject();
        //5、登录名和密码
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("feng","111111");

       try {
            //6、登录
            subject.login(usernamePasswordToken);
            //7、判断登录情况
            if(subject.isAuthenticated()){
                System.out.println("登录成功");
            }

            if(subject.hasRole("user")){
                System.out.println("拥有user权限");
            }

           if(subject.isPermitted("user:add")){
               System.out.println("拥有:user:add");
           }
           if(subject.isPermitted("user:delete")){
               System.out.println("拥有:user:delete");
           }
        } catch (AuthenticationException e) {
            e.printStackTrace();
            System.out.print("登录成失败");
        }
    }

 

 

4、以上自定义realm的时候需要注意几点

4.1写自定义realm时需要继承:AuthorizingRealm

4.2需要实现三个方法

     第一个:

@Override
    public String getName() {
        return "myRealm";
    }

   第二个:

/**
     * 身份检验
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        /**
         * 获取用户名
         */
        String username = (String)authenticationToken.getPrincipal();
        /**
         * 假设通过用户名从数据库获取用户密码
         */
        String password = "78a5940ee29370a687489906a35abb2c";
        String salt = "stx";

        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,password, ByteSource.Util.bytes(salt),getName());
        return simpleAuthenticationInfo;
    }

 

第三个:

 /**
     * 授权
     * @param principalCollection
     * @return
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        /**
         * 获取用户名
         */
        String username =(String)principalCollection.getPrimaryPrincipal();

        /**
         * 获取该用户对应的权限
         */
        List<String> listRole = new ArrayList<String>();
        listRole.add("user");
        listRole.add("admin");

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        for (String role:listRole) {
            authorizationInfo.addRole(role);
        }


        List<String> listPermssion = new ArrayList<String>();
        listPermssion.add("user:add");
        listPermssion.add("user:update");
        for (String permssion:listPermssion) {
            authorizationInfo.addStringPermission(permssion);
        }
        return authorizationInfo;
    }

 4.3在自定义realm中使用了加密,和盐值,在ini配置文件中需要设置凭证匹配器

#配置凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher
credentialsMatcher.hashAlgorithmName=md5
credentialsMatcher.hashIterations=2

#配置自定义的realm
myRealm=com.feng.realm.MyRealm
myRealm.credentialsMatcher=$credentialsMatcher

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值