shiro身份认证入门

shiro介绍

1、什么是shiro
shiro是Apache的一个开源框架,一个权限管理的框架,实现用户认证、用户授权。不仅可以实现web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,shiro属于轻量级框架。

2、shiro架构
在这里插入图片描述
如图可知:shiro架构分为几个部分:
subject:主体,可以是用户或者程序,主体是访问系统,系统需要对主体进行认证、授权。
securityManager:安全管理器,主体进行认证和授权都是通过securityManager进行。
authenticator:认证器,主体进行认证最终通过authenticator进行的。
authorizer:授权器,主体进行授权最终通过authorizer进行的。
sessionManager:web应用中一般是用web容器对session进行管理,shiro也提供一套session管理方法。
cache Manager:缓存管理器,主要对session和授权数据进行缓存,比如将授权数据通过cache Manager进行缓存管理,和redis整合对缓存数据进行管理。
realm:域,领域,相当于是数据源,通过realm存取认证、授权相关数据。
注意:在realm中存储授权和认证的逻辑。
cryptography:密码管理,提供了一套加密/加密的组件,方便开发。比如提供常用的散列,加解密等功能。md5
3、shiro的jar包(一下是maven项目的依赖形式)

<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-web</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-ehcache</artifactId>
			<version>1.2.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-quartz</artifactId>
			<version>1.2.3</version>
		</dependency>

也可以通过引入shiro-all包括shiro所有的包:
	<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-all</artifactId>
			<version>1.2.3</version>
		</dependency>

4、shiro认证流程
在这里插入图片描述
5、shiro入门程序
1、jar包
shiro-core-1.2.3.jar
2、测试程序
(1)ini文件的形式进行处理,在项目下创建config/shiro-1.ini文件
内容:

[users]
zhangsan=123
lisi=1233

(2)代码

package com.zhou.dado.shiro1;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.apache.shiro.mgt.SecurityManager;
import org.junit.Test;

/**
 * 认证代码
 */

public class Test1 {

    @Test
    public void testLoginLogout(){
        //构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境
        Factory<SecurityManager> factory=new IniSecurityManagerFactory("config/shiro-1.ini");

        //创建SecurityManager
        SecurityManager securityManager=factory.getInstance();

        //将SecurityManager设置当前的运行环境中
        SecurityUtils.setSecurityManager(securityManager);

        //从SecurityUtils里面创建一个subject
        Subject subject=SecurityUtils.getSubject();

        //在认证提交前准备token(令牌),这里的账号和密码,将来是用户输入进去
        UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123");
        //执行认证提交
        subject.login(token);

        boolean isAuthenticated=subject.isAuthenticated();

        System.out.println("是都认证通过:"+isAuthenticated);
    }

}

(3)认证流程
1、创建token令牌,token中有用户提交的认证信息即账号和密码
2、执行subject.login(tocken),最终由securityManager通过Authenticator进行认证
3、Authenticator的实现ModularRealmAuthenticator调用realm从ini配置文件取用户真实的账号和密码,这里使用的是Inirealm(shiro自带)
4、Inirealm先根据token中的账号去ini中找该账号,如果找不到则给
ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。

6、自定义realm
上边的程序使用的是shiro自带的inirealm,从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所有需要自定义realm。
1、shiro提供的realm
最基础的是realm接口,CachingRealm负责缓存处理,AuthenticationRealm负责认证,AuthorizingRealm负责授权,通常自定义的realm继承AuthorizingRealm。
2、自定义realm

package com.zhou.dado.shiro1;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

public class Test2_Realm extends AuthorizingRealm {

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

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
       //从token中获取和用户身份信息
        String username=(String)token.getPrincipal();
        //拿username从数据库中查询
        //....
        //如果查询不到则返回null
        if(!username.equals("zhangsan")){//这里模拟查询不到
            return null;
        }
        //获取从数据库查询出来的用户密码
        String password="123";//这里使用静态数据模拟

        //返回认证信息由父类AuthenticatingRealm进行认证
        SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(username,password,getName());
        return simpleAuthenticationInfo;
    }

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
}

@Test
    public void testLoginLogoutRealm(){
        //构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境
        Factory<SecurityManager> factory=new IniSecurityManagerFactory("config/shiro-realm.ini");

        //创建SecurityManager
        SecurityManager securityManager=factory.getInstance();

        //将SecurityManager设置当前的运行环境中
        SecurityUtils.setSecurityManager(securityManager);

        //从SecurityUtils里面创建一个subject
        Subject subject=SecurityUtils.getSubject();

        //在认证提交前准备token(令牌),这里的账号和密码,将来是用户输入进去
        UsernamePasswordToken token=new UsernamePasswordToken("zhangsan","123");
        //执行认证提交
        subject.login(token);

        boolean isAuthenticated=subject.isAuthenticated();

        System.out.println("是都认证通过:"+isAuthenticated);
    }

ini配置:config/shiro-realm.ini

[main]
#自定义 realm
customRealm=com.zhou.dado.shiro1.Test2_Realm
#将realm设置到securityManager
securityManager.realms=$customRealm

7、散列算法
散列算法一般用于生成一段文本的摘要信息,散列算法不可逆,将内容可以生成摘要,无法将摘要转换成原始内容。散列算法常用语对密码进行散列,常用的散列算法有md5,sha。一般散列算法需要提供一个salt(盐)与原始内容生成摘要信息。这样做的目的是为了安全性,比如111111的md5值是96e79218965eb72c92a549dd5a330112,拿着96e79218965eb72c92a549dd5a330112去md5破解网站和容易进行破解,如果要是对11111的salt(盐,一个随机数)进行散列,这样虽然密码都是111111加不同的盐会生成不同的散列值。
例子:

//md5加密,不加盐
		String password_md5 = new Md5Hash("111111").toString();
		System.out.println("md5加密,不加盐="+password_md5);
		
		//md5加密,加盐,一次散列
		String password_md5_sale_1 = new Md5Hash("111111", "eteokues", 1).toString();
		System.out.println("password_md5_sale_1="+password_md5_sale_1);
		String password_md5_sale_2 = new Md5Hash("111111", "uiwueylm", 1).toString();
		System.out.println("password_md5_sale_2="+password_md5_sale_2);
		//两次散列相当于md5(md5())

		//使用SimpleHash
		String simpleHash = new SimpleHash("MD5", "111111", "eteokues",1).toString();
		System.out.println(simpleHash);

在realm中使用:

package com.zhou.dado.shiro1;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

public class Test2_RealmMd5 extends AuthorizingRealm {

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

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
       //从token中获取和用户身份信息
        String username=(String)token.getPrincipal();
        //根据用户账号从数据库取出盐和加密后的值,这里是静态数据,如果账号没有找到用户信息则返回null,shiro抛出异常“账号不存在”
        //按照固定规则加密码结果,此密码要在数据库存储,原始密码是111111,盐eteokues
        String password="cb571f7bd7a6f73ab004a70322b963d5";//这里使用静态数据模拟
        String salt="eteokues";
        //返回认证信息由父类AuthenticatingRealm进行认证
        SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(username,password, ByteSource.Util.bytes(salt),getName());
        return simpleAuthenticationInfo;
    }

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
}

realm配置:

[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=1

#将凭证匹配器设置到realm
customRealm=com.zhou.dado.shiro1.Test2_Realm
customRealm.credentialsMatcher=$credentialsMatcher
securityManager.realms=$customRealm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值