Shiro简单使用

(1)Subject:代表了当前"用户",这个用户不一定是一个具体的人,       与当前应用交互的任何东西都是Subject。

(2)SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且其管理着所有Subject;可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC中DispatcherServlet的角色。

(3)Authenticator:认证。验证用户是否合法,也就是登录。利用Shiro进行密码匹配,帮我们完成登录。

(4)Authorizer:授权。授予谁具有访问哪些资源的权限;即判断用户是否能做事情,常见的如:当我们点一个链接或按钮时,Shiro会帮我们判断有没有这个权限。验证某个用户是否拥有某个角色,或者细粒度的验证某个用 户对某个资源是否具有某个权限。

(5)Session Manager:会话管理。用户登录后的用户信息通过Session Manager来进行管理,不管是什么应用中,比如:Web应用、JavaSE应用。之前我们在Web环境下,使用的是HttpSession。那使用Shiro的情况下即便是在非Web环境下,就是说在JavaSE环境系也可以使用session,这个session就是Shiro帮我们提供的。

(6)SessionDAO 即会话 dao,是对 session 会话操作的一套接口,比如要将 session 存储到数据库,可以通过 jdbc 将会话存储到数据库。

(7)Cache Manager缓存管理。Shiro提供了对缓存的支持,支持多种缓存:如:ehcache,还支持缓存数据库:Redis。

(8)Cryptogarphy:加密。提供了常见的一些加密算法,使得在应用中可以很方便的实现数据安全,并且使用很便捷。

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

环境搭建

 <!--配置shiro核心包-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!--junit包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>
 

Shiro认证

认证过程

代码演示

public class TestShiro {
    //创建Realm对象,充当数据源
    SimpleAccountRealm realm = new SimpleAccountRealm();

    @Before
    public void addData(){
        //存放原始数据
        realm.addAccount("andy","123456");
    }

    //认证
    @Test
    public void testAuthenticator(){
        //创建SecurityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //设置SerurityManager
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //设置realm
        defaultSecurityManager.setRealm(realm);
        //获取用户
        Subject subject = SecurityUtils.getSubject();
        //根据用户提交的数据获取token
        UsernamePasswordToken token = new UsernamePasswordToken("andy","123456");
        //数据认证
        subject.login(token);
        //获取认证结果
        System.out.println("isAuthenticated:"+subject.isAuthenticated());
        //登出
        subject.logout();
        System.out.println("登出后isAuthenticated:"+subject.isAuthenticated());
    }

输出结果

Shiro授权

代码演示

public class TestShiro {
    //创建Realm对象,充当数据源
    SimpleAccountRealm realm = new SimpleAccountRealm();

    @Before//测试授权
    public void addUser2(){
        realm.addAccount("xiaoming","123456","admin","user");
    }

    //授权
    @Test
    public void testAuthorizer(){
        //构建Security
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //设置数据源
        defaultSecurityManager.setRealm(realm);
        //设置Securitymanager环境
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //获取用户
        Subject subject = SecurityUtils.getSubject();
        //根据用户提交的数据获取Token
        UsernamePasswordToken token = new UsernamePasswordToken("xiaoming","123456");
        //数据认证
        subject.login(token);
        if(subject.isAuthenticated()){
            //角色认证
            //subject.checkRole("user");
            subject.checkRoles("user","admin");
            System.out.println("角色验证通过");
        }
    }

输出结果

Shiro权限认证

在resources下创建user.ini

[users]
xiaoming=123456,admin
[roles]
admin=user:delete,user:update

代码演示

package com.cboy.test;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;

public class TestShiro2 {
    //创建Realm模拟数据源,引入
    IniRealm iniRealm = new IniRealm("classpath:user.ini");
    @Test
    public void testAuthorizer(){
        //构建SecurityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //引入数据源
        defaultSecurityManager.setRealm(iniRealm);
        //设置SecurityManager环境
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //创建"用户"
        Subject subject = SecurityUtils.getSubject();
        //获取用户传来的数据,创建token与数据源中做对比
        UsernamePasswordToken token = new UsernamePasswordToken("xiaoming","123456");
        //认证
        subject.login(token);
        System.out.println("isAuthenticated:"+subject.isAuthenticated());
        //subject.isAuthenticated()如果正确返回true
        if(subject.isAuthenticated()){
            //检查角色
            subject.checkRoles("admin");
            //检查权限
            subject.checkPermission("user:delete");
            System.out.println("授权成功");
        }


    }
}

输出结果

链接数据库操作

导入mysql与druid的jar包坐标信息

<!-- MySQL的驱动jar -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.45</version>
        </dependency>

        <!-- druid连接池的依赖jar-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>

数据库表数据:

代码演示:

package com.cboy.test;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.subject.Subject;
import org.junit.Test;

public class TestShirojdbc {
    //使用druid连接池,连接数据源
    DruidDataSource dataSource = new DruidDataSource();
    //代码块,不用加@Before注解,在初始化时自动加载
    {
        //配置数据源
        dataSource.setUrl("jdbc:mysql://localhost:3306/shirotest");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
    }

    @Test
    public void testAuthorizer(){
        //创建数据源
        JdbcRealm jdbcRealm = new JdbcRealm();
        //将数据源写入
        jdbcRealm.setDataSource(dataSource);
        //将查询权限的权限打开,默认为false关闭
        jdbcRealm.setPermissionsLookupEnabled(true);
        //设置查询角色的sql语句,用于认证
        String sql_user = "select password from shiro_users where username=?";
        //执行自定义认证的sql
        jdbcRealm.setAuthenticationQuery(sql_user);
        //设置查询角色的sql语句,用于角色认证
        String sql_roles = "select role_name from user_roles where username = ?";
        //执行角色认证
        jdbcRealm.setUserRolesQuery(sql_roles);
        //设置查询权限的sql语句,用于查询权限
        String sql_permissions = "select permission from roles_permissions where role_name = ?";
        //执行权限认证
        jdbcRealm.setPermissionsQuery(sql_permissions);
        //构造SecurityManager环境
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //存入数据源
        defaultSecurityManager.setRealm(jdbcRealm);
        //设置SecurityManager环境
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //获取用户
        Subject subject = SecurityUtils.getSubject();
        //模拟前台传来的数据
        UsernamePasswordToken token = new UsernamePasswordToken("xiaoming","123456");
        //认证
        subject.login(token);
        //打印是否认证成功
        System.out.println("isAuthenticated:"+subject.isAuthenticated());
        //判断是否成功,进行后续操作
        if(subject.isAuthenticated()){
            subject.checkRole("admin");
            System.out.println("角色认证通过");
            subject.checkPermission("user:delete");
            System.out.println("权限认证通过");
        }

    }


}

输出结果:

Shiro自定义Realm+加密加盐

自定义realm

package com.cboy.test;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.HashMap;
import java.util.Map;

/**
 * 自定义Realm
 */
public class CustomRealm extends AuthorizingRealm {
    Map<String,String> userMap = new HashMap<String, String>();
    {
        //不加密
        //userMap.put("andy","123456");
        //加密
        //userMap.put("andy","e10adc3949ba59abbe56e057f20f883e");
        //加盐
        userMap.put("andy","48e231e66ff8943db0f6d2b6cb6536d2");
        super.setName("安迪");
    }
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    //自定义认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1.从主体传来的信息中获取用户名
        String username = (String)authenticationToken.getPrincipal();
        //2.通过用户名从数据库中获取凭证
        String password = getPassWordbyUsername(username);
        //如果没有查到
        if(password==null){
            return null;
        }
        //设置盐值
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo("andy",password,"安迪");
        //设置盐值
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("xiaoming"));
        return authenticationInfo;


    }

    //模拟读取数据
    private String getPassWordbyUsername(String username){
        return userMap.get(username);
    }

    //计算加密后的值
    public static void main(String[] args) {
        //加密
       // Md5Hash md5 = new Md5Hash("123456");
        //加盐
        Md5Hash md5 = new Md5Hash("123456","xiaoming");
        System.out.println(md5);
    }
}

测试

package com.cboy.test;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
import org.junit.Test;

public class TestShirozdy {

    @Test
    public void testShirozdy(){
        //配置数据源
        CustomRealm customRealm = new CustomRealm();
        //创建SecurityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //设置数据源
        defaultSecurityManager.setRealm(customRealm);
        //创建加密对象
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //加密名称
        matcher.setHashAlgorithmName("md5");
        //加密次数
        matcher.setHashIterations(1);
        //在Realm中设置加密对象
        customRealm.setCredentialsMatcher(matcher);
        //设置SerurityManager
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //获取用户
        Subject subject = SecurityUtils.getSubject();
        //根据用户提交的数据获取token
        UsernamePasswordToken token = new UsernamePasswordToken("andy","123456");
        //数据认证
        subject.login(token);
        //获取认证结果
        System.out.println("isAuthenticated:"+subject.isAuthenticated());

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值