文档章节

Shiro入门教程

whatwhowhy
 whatwhowhy
发布于 2016/08/19 15:12
字数 1395
阅读 50
收藏 0

Shiro其实很简单,作为入门教程,这里我就从项目搭建开始讲起。

Shiro依赖的jar

commons-loggingshiro-coredruidmysql-connector-java
构建maven的pom.xml文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.xttblog.shiro-demo1</groupId>
  <artifactId>shiro-demo1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
            <scope>test</scope>
        </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>
</project>
配置shiro.ini文件

内容如下:
[users]
shiro=123
xttblog=123

定义实体及关系

drop database if exists shiro;
create database shiro;
use shiro;
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `roles_permissions`;
CREATE TABLE `roles_permissions` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(100) DEFAULT NULL,
  `permission` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_roles_permissions` (`role_name`,`permission`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
INSERT INTO `roles_permissions` VALUES ('1', 'role1', '+user1+10');
INSERT INTO `roles_permissions` VALUES ('3', 'role1', '+user2+10');
INSERT INTO `roles_permissions` VALUES ('2', 'role1', 'user1:*');
INSERT INTO `roles_permissions` VALUES ('4', 'role1', 'user2:*');
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) DEFAULT NULL,
  `password` varchar(100) DEFAULT NULL,
  `password_salt` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_users_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO `users` VALUES ('2', 'shiro', '123', null);
DROP TABLE IF EXISTS `user_roles`;
CREATE TABLE `user_roles` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) DEFAULT NULL,
  `role_name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_user_roles` (`username`,`role_name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO `user_roles` VALUES ('1', 'shiro', 'role1');
INSERT INTO `user_roles` VALUES ('2', 'shiro', 'role2');
定义Realm
package com.xttblog.shiro.realm;
 
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;
 
/**
 * Shiro框架学习demo
 * 业余草:www.xttblog.com
 * QQ1群:135430763(已满)
 * QQ2群:454796847
 * @author 涛哥
 * @date 2016年8月8日14:46:10
 */
public class MyRealm implements Realm{
    public String getName() {
        return "myrealm";
    }
 
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken; //仅支持UsernamePasswordToken类型的Token
    }
 
    //Shiro的认证过程最终会交由Realm执行,这时会调用Realm的getAuthenticationInfo(token)方法
    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        /**
         * 1、检查提交的进行认证的令牌信息
         * 2、根据令牌信息从数据源(通常为数据库)中获取用户信息
         * 3、对用户信息进行匹配验证。
         * 4、验证通过将返回一个封装了用户信息的AuthenticationInfo实例。
         * 5、验证失败则抛出AuthenticationException异常信息。
         */
        String username = (String)token.getPrincipal();  //得到用户名
        String password = new String((char[])token.getCredentials()); //得到密码
        if(!"shiro".equals(username)) {
            throw new UnknownAccountException(); //如果用户名错误
        }
        if(!"123".equals(password)) {
            throw new IncorrectCredentialsException(); //如果密码错误
        }
        //如果身份认证验证成功,返回一个AuthenticationInfo实现;
        return new SimpleAuthenticationInfo(username, password, getName());
    }
}
AuthenticationToken接口

AuthenticationInfo的两个作用:
1、如果Realm是AuthenticatingRealm子类,则提供给AuthenticatingRealm内部使用的CredentialsMatcher进行凭据验证;(如果没有继承它需要在自己的Realm中自己实现验证)
2、提供给SecurityManager来创建Subject(提供身份信息)

Shiro测试用例
package com.xttblog.shiro.auth;
 
import junit.framework.Assert;
 
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
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.util.ThreadContext;
import org.junit.After;
import org.junit.Test;
/**
 * Shiro框架学习demo
 * 业余草:www.xttblog.com
 * QQ1群:135430763(已满)
 * QQ2群:454796847
 * @author 涛哥
 * @date 2016年8月8日14:46:10
 */
public class LoginLogoutTest {
     
    /**
     * 通过数据源为:用户名/密码的键值对配置文件验证身份
     */
    @Test
    public void testHelloworld() {
        //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
        Factory<org.apache.shiro.mgt.SecurityManager> factory =
                new IniSecurityManagerFactory("classpath:shiro.ini");
 
        //2、得到SecurityManager实例 并绑定给SecurityUtils
        org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
 
        //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("shiro", "123");
 
        try {
            //4、登录,即身份验证
            subject.login(token);
        } catch (AuthenticationException e) {
            //5、身份验证失败
            System.out.println("身份验证失败:www.xttblog.com");
        }
        Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录
        //6、退出
        subject.logout();
    }
 
    /**
     * 通过数据源为:自定义Realm验证身份
     */
    @Test
    public void testCustomRealm() {
        //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
        Factory<org.apache.shiro.mgt.SecurityManager> factory =
                new IniSecurityManagerFactory("classpath:shiro-realm.ini");
 
        //2、得到SecurityManager实例 并绑定给SecurityUtils
        org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
 
        //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("shiro", "123");
 
        try {
            //4、登录,即身份验证
            subject.login(token);
        } catch (AuthenticationException e) {
            //5、身份验证失败
            e.printStackTrace();
        }
 
        Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录
 
        //6、退出
        subject.logout();
    }
 
    /**
     * 通过数据源为:多个自定义Realm验证身份
     */
    @Test
    public void testCustomMultiRealm() {
        //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
        Factory<org.apache.shiro.mgt.SecurityManager> factory =
                new IniSecurityManagerFactory("classpath:shiro-multi-realm.ini");
 
        //2、得到SecurityManager实例 并绑定给SecurityUtils
        org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
 
        //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("shiro", "123");
 
        try {
            //4、登录,即身份验证
            subject.login(token);
        } catch (AuthenticationException e) {
            //5、身份验证失败
            e.printStackTrace();
        }
 
        Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录
 
        //6、退出
        subject.logout();
    }
 
    /**
     * 通过数据源为:数据库的方式验证身份
     */
    @Test
    public void testJDBCRealm() {
        //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
        Factory<org.apache.shiro.mgt.SecurityManager> factory =
                new IniSecurityManagerFactory("classpath:shiro-jdbc-realm.ini");
 
        //2、得到SecurityManager实例 并绑定给SecurityUtils
        org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
 
        //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
        Subject subject = SecurityUtils.getSubject();
        //如果用户名不存在,则会报org.apache.shiro.authc.UnknownAccountException: No account found for user [xx用户名]异常
        UsernamePasswordToken token = new UsernamePasswordToken("shiro", "123");
         
        try {
            //4、登录,即身份验证
            subject.login(token);
        } catch (AuthenticationException e) {
            //5、身份验证失败
            e.printStackTrace();
        }
        Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录
        //6、退出
        subject.logout();
    }
 
    @After
    public void tearDown() throws Exception {
        ThreadContext.unbindSubject();//退出时请解除绑定Subject到线程 否则对下次测试造成影响
    }
}

其他的一些配置文件我就不贴了,我已共享到了群空间!或者到csdn进行下载!

转载请注明出处:业余草: » Shiro入门教程

本文转载自:http://www.xttblog.com/?p=669

上一篇: java异常总结
下一篇: java导出excel
whatwhowhy

whatwhowhy

粉丝 14
博文 50
码字总数 16265
作品 0
杭州
程序员
私信 提问
Shiro权限控制框架入门1:Shiro的认证流程以及基本概念介绍

前言:我在最开始学习Shiro这个框架时,在网上搜索到的一个介绍比较全面的教程是:《跟我学Shiro》系列教程。但是在我看了他写的前几篇文章后,我发现虽然他在这个系列教程中把shiro的一些特...

pangfc
2017/01/06
0
0
【shiro】入门程序

Apache Shiro是一个强大的且易用的java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,可以快速,轻松的获得任何应用程序,从最小的移动应用程序到最大的网络和...

binggetong
2017/12/19
0
0
Apache Shiro 10分钟入门教程

1.简介 欢迎来到Apache Shiro的10分钟教程! 通过阅读这个快速简单的教程,您将充分了解开发人员如何在其应用程序中使用Shiro。而且你应该可以在10分钟内做到这一点。 2.概览 什么是Apache ...

尘_竹
2018/05/22
0
0
Apache Shiro 快速入门教程,shiro 基础教程

第一部分 什么是Apache Shiro 1、什么是 apache shiro : Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 如同 spring security 一样都是是一个权...

kevin728971010
2016/10/25
862
3
亲手打造:构建第一个Apache Shiro应用

构建第一个Apache Shiro应用 如果您是Apache Shiro的新手,这个简短的教程将向您展示如何设置基于Apache Shiro的初始的且非常简单的安全应用。我们将一路讨论Shiro的核心概念,以帮助您熟悉S...

尘_竹
2018/05/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

parseint和isNaN用法

本文转载于:专业的前端网站➭parseint和isNaN用法 <!doctype html><html><head><meta charset="utf-8"><title>无标题文档</title></head><body><script> var a='12'; alert......

前端老手
52分钟前
7
0
Kylin 精确去重在用户行为分析中的妙用

作者:史少锋,Apache Kylin committer & PMC,2019/10/11 在上次文章《如何在 1 秒内做到大数据精准去重》中,我们介绍了 Apache Kylin 为什么要支持大数据集上的精确去重,以及基于 Bitmap...

ApacheKylin
今天
5
0
学习记录(二) es6基本语法(rest参数,模板化,axios模块,拦截器)

日常学习记录 模块化:把一个大文件分成多个小文件,按照一定规范进行拼接 es5写法: 导出:module.exports = 数据 导入:require("路径") /路径未添加后缀名时 //默认添加.js //把路径作为文件名...

Pole丶逐
今天
4
0
以程序员的角度怎么购买一台「性价比高的电视」

前俩天有小伙伴在我的文章下留言,说能否把 【国内电视机都介绍一下】,今天我已在TV端开发多年的程序员的角度。谈谈已程序员的角度如何购买一台性价比高的电视。 国内大的电视机品牌介绍 长...

我们都很努力着
今天
5
0
PhotoShop 色调:理解直方图/RGB通道信息

一、直方图:图表的形式,展示图像像素分布的情况 1.平均值:表示平均亮度 2.标准偏差值:表示亮度值范围内的中间值 3.像素: 表示用于计算直方图的像素总数 4.色阶:显示指针下面的区域亮度...

东方墨天
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部