shiro的入门级使用

shiro框架的简单入门使用

1.shiro框架的简介

1.1 shiro框架是什么

shiro是apache公司的产品,是一款轻量级的java安全框架,Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。
现在市场上使用的比较多的安全框架还有就是Spring公司的security框架,它是一款重量级的框架。shiro是一个轻量级的框架,可以快速,轻松的获取任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。它支持多种语言的应用程序,shiro支持web mvc的环境,也支持其他各种语言的程序,比如c,c#…所以shiro的使用非常灵活方便

1.2 shiro框架的核心

shiro的身份验证、授权、密码学、会话管理是其核心,是shrio的四大基石。
Authentication身份认证:对一个用户的身份进行验证,判断这个用户是否登录,是否是该系统的合法用户。
Authorization授权:即对通过认证之后的用户,对其权限进行判断,判断该用户是否有执行某一功能的权限。
Cryptography密码学:通过shiro提供的加密的算法,对数据进行加密,使数据安全同时易于使用。
Session Management会话管理:shiro提供的会话管理,不依赖与web的session,所以shiro可以在非web的环境下使用。

2.shiro框架

2.1 从shiro外部来看

在这里插入图片描述Application code:就是外部应用程序
Subject:就是外部应用程序交互的用户,其实就是当前用户对象
SecurityManager:安全管理器,这个是核心对象,用来管理的所有的Subject对象,就是用来管理所有的用户的。
Realm:shiro是从 realm上获取到安全数据的,即用户,角色,权限数据,就是我们的元数据都是从realm中获取的。

2.2 从shiro内部来看

在这里插入图片描述

shiro的简单使用

3.1 导入shiro的依赖包
<dependencies>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.4.0</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
3.2 准备元数据,自定义一个realm类

在这里插入图片描述
上面是shiro中的realm的结构体系,realm是一个顶层接口,之前说过realm是获取用户,角色,权限数据的,下面有一个实现类jdbcrealm,通过这个可以从数据库中获取到用户、角色、权限这些数据。
不过我们一般都是使用自定义的realm,realm虽然是数据源,但它不仅仅是获取数据的,我们在自定义的realm类中还有认证授权验证的相关代码。
下面是自定义的realm类:我们自定义的时候不要实现realm顶层接口,因为需要复写所以抽象方法,而是通过实现AuthorizingRealm类,这样只需要覆写doGetAuthenticationInfo登录认证和doGetAuthorizationInfo授权认证的方法。

public class MyRealm extends AuthorizingRealm {
    @Override
    public String getName() {
        return "MyRealm";
    }
    /**身份验证的方法
     * @param authenticationToken : 参数authenticationToken对象也有两个属性:principal(对象) 和 credentials(对象)
     * @return :返回AuthenticationInfo对象,该对象有两个属性:principals(集合) 和 credentials(对象)
     * @throws AuthenticationException
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1.通过authenticationToken获取到用户信息,如果要获取到username和password等信息就需要强转
        String username = ((UsernamePasswordToken) authenticationToken).getUsername();
        //拿到用户名以后就要进行身份验证了
        if(username==null){
            //返回一个空表示账户错误
            return null;
        }
        //然后通过用户名拿到密码:
        String pwd = getPwd(username);
        //拿到用户名和密码以后就调用Simp
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, pwd, getName());
        return simpleAuthenticationInfo;
    }
    /**
     *
     * @param principalCollection 参数:是一个principals集合,注意我们在身份验证方法的返回值SimpleAuthenticationInfo对象
     *                            中,new这个对象的第一个参数是principal对象,如果传入的是username,那么这里取出来的就是username
     *                            传入的是一个对象,在授权验证的参数中取出来的就是一个对象
     * @return :返回一个AuthorizationInfo对象,其子类是SimpleAuthorizationInfo,这个对象有两个重要属性:getroles:获取到用户的角色
     *          getObjectPermissions获取到角色对应的权限
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //一个主体可以有多个principals,但只有一个Primaryprincipal,一般是用户名/密码/手机号。
        //先获取到Primaryprincipal,然后上面传入的username,就可以直接强转为username
        String username = (String)principalCollection.getPrimaryPrincipal();
        //通过SimpleAuthorizationInfo来设置用户的角色和权限,后期这些数据是从数据库中拿到的
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //为该用户设置角色---角色使用的是set集合
        Set<String> set = new HashSet<String>();
        set.add("admin");
        simpleAuthorizationInfo.setRoles(set);
        //为这个角色赋予权限,使用的还是set集合,可以使用一个先清除一下即可
        set.clear();
        set.add("employee:*");
        simpleAuthorizationInfo.setStringPermissions(set);
        //然后将设置好的SimpleAuthorizationInfo对象返回去
        return simpleAuthorizationInfo;
    }
    //我们还没有连接数据库,所以在这里定义一个方法,获取一个密码数据
    String getPwd(String username){
        //如果用户名是admin就返回123456
        if("root".equals(username)){
           return "123456";
        }
        //否则密码返回空
        return null;
    }
}
3.3 测试

我们自定义的realm类中的用户,角色,权限是元数据,因为没有连接数据都是假数据

@Test
public void testMyRealm()throws Exception{
    //首选要准备元数据,即创建MyRealm对象
    MyRealm myRealm = new MyRealm();
    //然后拿到securityManager对象加载元数据
    DefaultSecurityManager securityManager = new DefaultSecurityManager();
    securityManager.setRealm(myRealm);
    //配置上下文环境
    SecurityUtils.setSecurityManager(securityManager);
    //拿到当前的用户信息
    Subject user = SecurityUtils.getSubject();
    //判断用户是否登录
    if(!user.isAuthenticated()){
        //没有登录就模拟登录,使用UsernamePasswordToken对象
        UsernamePasswordToken token = new UsernamePasswordToken("root","123456");
        try {
            user.login(token);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            System.out.println("用户名或密码错误");
        }
    }
    //打印用户登录了没有
    System.err.println("是否登录"+user.isAuthenticated());
    //测试该用户是否有这个角色
    System.err.println("是否有该角色"+user.hasRole("admin"));
    //测试权限
    System.err.println("是否有权限"+user.isPermitted("employee:index"));
    //登出
    user.logout();;
    System.err.println("是否登录"+user.isAuthenticated());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值