引入

上一篇在讲解Realm简介时,介绍过Realm包含大概4类缺省的Realm,本章主要讲解:

1)IniRealm的用法;

2)JdbcRealm基于mysql   默认表及查询语句实现认证、授权;

3)JdbcRealm基于mysql自定义表及查询语句实现认证、授权。

4)自定义Realm。

在上一张讲解时,截图了一张Realm的类图,这里需要重复引用下:

从图中,我们可以看出AuthenticatingRealm是AuthorizingRealm的父类:

1)AuthenticatingRealm类内部对外提供了抽象认证接口:

2)AuthorizingRealm    类内部对外提供了抽象授权接口:

3)因AuthorizingRealm继承了AuthenticationgRelam,因此AuthorizingRealm具有了认证、授权接口。

因此后边讲解自定义Realm时,我们会采用继承 AuthorizingRealm的方式去实现自定义Realm。

IniRealm的用法

在Shiro缺省的几种实际上IniRealm和PropertiesRealm的用法最为类似。

主要是将用户信息、用户角色、用户资源信息存储到相应的*.ini文件中,认证和授权时从文件中查找相应的数据是否存在。

*.ini主要分为4个部分:[main]、[users]、[roles]、[urls]

示例:
shiro-config.ini文件:

[main]
#authenticator
#配置验证器
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
#配置策略
authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
#将验证器和策略关联起来
authenticator.authenticationStrategy=$authenticationStrategy
securityManager.authenticator=$authenticator #authorizer
authorizer=org.apache.shiro.authz.ModularRealmAuthorizer
permissionResolver=org.apache.shiro.authz.permission.WildcardPermissionResolver
authorizer.permissionResolver=$permissionResolver
securityManager.authorizer=$authorizer #realm
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shiro
dataSource.username=root
dataSource.password=123456 jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$dataSource
jdbcRealm.permissionsLookupEnabled=true
securityManager.realms=$jdbcRealm
[users]
#提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2
zhangsan=123,admin,member
lisi=1234,member [roles]
#提供了角色及权限之间关系的配置,角色=权限1,权限2
admin=article:update,article:delete,article:query
member=article:query [urls]
#用于web,提供了对web url拦截相关的配置,url=拦截器[参数],拦截器
/index.html = anon
/admin/** = authc, roles[admin], perms["article:query"]

1)[main]模块:

主要负责shiro相关配置:securityManger,realm,credentialsMatcher,authenticator,authorizer等。
给securityManger配置authenticator(认证器),authenticator.authenticationStrategy(认证器的多realm策略)
给securityManger配置authorizer(授权器),authorizer.permissionResolver(授权器的资源解析器)
给securityManger配置realms,realm(认证、授权 存储器).属性设置(JdbcRealm.dataSource/JdbcRealm.permissionLookupEnabled)
给realm配置credentialsMatcher(凭证匹配器:它内部包含采用哪种方式进行加密:md5、sha256,slat[盐值],hashIterations[加密迭代多少次])

2)[users]模块:
提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2,示例:

[users]
zhangsan=123,admin,member
lisi=1234,member

3)[roles]模块:
提供了角色及权限之间关系的配置,角色=权限1,权限2,示例:

[roles]
admin=article:update,article:delete,article:query
member=article:query

4)[urls]模块:
用于web,提供了对web url拦截相关的配置,url=拦截器[参数],拦截器,示例:

[urls]
/index.html = anon
/admin/** = authc, roles[admin], perms["article:query"]

上边配置信息在shiro比较早点版本(shiro1.4.2就不是特别好用了)可使用IniSecurityManagerFactory进行加载:

Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-config.ini");
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); //将SecurityManager设置到SecurityUtils 方便全局使用
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
subject.login(token); Assert.assertTrue(subject.isAuthenticated());

实际上边配置shiro-config.xml中[main]配置信息等同于:

        DefaultSecurityManager securityManager = new DefaultSecurityManager();

        // #配置验证器
ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
// #配置策略
AtLeastOneSuccessfulStrategy authenticationStrategy = new AtLeastOneSuccessfulStrategy();
// #将验证器和策略关联起来
authenticator.setAuthenticationStrategy(authenticationStrategy);
securityManager.setAuthenticator(authenticator); // #授权器
ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
WildcardPermissionResolver permissionResolver = new WildcardPermissionResolver();
authorizer.setPermissionResolver(permissionResolver);
securityManager.setAuthorizer(authorizer); DruidDataSource dataSource = new DruidDataSource();
{
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setUrl(
"jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
} JdbcRealm jdbcRealm = new JdbcRealm();
jdbcRealm.setDataSource(dataSource);
// JdbcRealm.permissionsLookupEnabled 默认为false,必须设置为true才能进行角色的授权。
jdbcRealm.setPermissionsLookupEnabled(true); HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("MD5");
credentialsMatcher.setHashIterations(8);
jdbcRealm.setCredentialsMatcher(credentialsMatcher); securityManager.setRealms(Arrays.asList(jdbcRealm));

使用时,通过SecurityUtils与securityManager进行关联,然后获取Subject对象,通过subject进行认证验证,授权验证,退出认证。

        SecurityUtils.setSecurityManager(securityManager);

        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
subject.login(token);
System.out.println("是否通过认证:" + subject.isAuthenticated()); System.out.println("是否拥有admin角色:" + subject.hasRole("admin"));
// 必须设置JdbcRealm为jdbcRealm.setPermissionsLookupEnabled(true)
// 是否拥有修改的权限
System.out.println("是否拥有user:update角色:" + subject.isPermitted("user:update")); subject.logout();
System.out.println("是否通过认证:" + subject.isAuthenticated());

IniRealm的使用示例:

1)认证用法:

配置文件 shiroAuthenticator.ini

#用来认证
#============================
#设置用户,可设置多名用户
[users]
# 用户名=密码
zhangsan=123
lisi=1234

用法测试:

    /**
* 测试认证
*/
@Test
public void testAuthenticator() {
// 1)根据IniRealm进行数据读取 *.ini 配置,另外也可以通过JdbcRealm读取数据中存储的信息,也可以采用内存存储方式,还可以用户自定义。
// Shiro从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager需验证用户身份,那么它需要从Realm获取响应的用户进行比较以确定用户身份是否合法;
// 也需要从Realm得到用户相应的角色、权限进行验证用户是否能进行操作;
// 可以把Realm看成DataSource。
Realm iniRealm = new IniRealm("classpath:shiroAuthenticator.ini"); // 2) 管理所有的Subject,负责认证、授权、会话以及缓存的管理。
// SecurityManager:安全管理器,即所有与安全有关的操作都会与SecurityManager交互;
// 且其管理所有Subject;
// 可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC中DispatcherServlet的角色。
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(iniRealm); SecurityUtils.setSecurityManager(defaultSecurityManager);
// Subject:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject。
// Subject代表了当前"用户",这个用户不一定就是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;
// 与Subject的所有交互都委托给SecurityManager;
// Subject其实是一个门面,SecurityManager才是实际的执行者;
Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
// 进行认证
subject.login(token); System.out.println("是否认证通过:" + subject.isAuthenticated());
}

2)授权的用法:

配置文件 shiroAuthorizer.ini

#用来授权
#===========================
#设置用户及用户角色
[users]
# 用户名=密码,角色
zhangsan=123,admin
lisi=1234,member #设置角色与角色权限
[roles]
# 角色=资源1,资源2
admin=user:delete,user:update,user:query
member=user:query

用法测试:

    /**
* 测试认证+授权
*/
@Test
public void testAuthorizer() {
Realm iniRealm = new IniRealm("classpath:shiroAuthorizer.ini");
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(iniRealm); SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
// 调用 Realm#getAuthenticationinfo()
subject.login(token); System.out.println("是否认证通过:" + subject.isAuthenticated()); // 调用 Realm#getAuthorizationinfo()
System.out.println("是否授权admin角色:" + subject.hasRole("admin"));
System.out.println("是否拥有user:update资源:" + subject.isPermitted("user:update"));
System.out.println("是否拥有user:delete资源:" + subject.isPermitted("user:delete"));
System.out.println("是否拥有user:create资源:" + subject.isPermitted("user:create")); subject.logout(); System.out.println("是否认证通过:" + subject.isAuthenticated()); System.out.println("是否授权admin角色:" + subject.hasRole("admin"));
System.out.println("是否拥有user:update资源:" + subject.isPermitted("user:update"));
System.out.println("是否拥有user:delete资源:" + subject.isPermitted("user:delete"));
System.out.println("是否拥有user:create资源:" + subject.isPermitted("user:create"));
}

JdbcRealm的用法

使用JdbcRealm内部默认表和查询SQL

JdbcRealm实际上在代码内部缺省在关系数据库中存在三张表:

`users`{id,username,password,password_salt}
`user_roles`{id,username,role_name}
`roles_permissions`{id,role_name,permission}

其实,从JdbcRealm内部定义的查询语句可以看出内置表结构:

    /**
* The default query used to retrieve account data for the user.
*/
protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?"; /**
* The default query used to retrieve account data for the user when {@link #saltStyle} is COLUMN.
*/
protected static final String DEFAULT_SALTED_AUTHENTICATION_QUERY = "select password, password_salt from users where username = ?"; /**
* The default query used to retrieve the roles that apply to a user.
*/
protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?"; /**
* The default query used to retrieve permissions that apply to a particular role.
*/
protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";

JdbcRealm使用时,需要在关系数据库中创建默认的那三张表,然后配置信息写入到对应表中。

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL,
`password` varchar(64) NOT NULL,
`password_salt` varchar(64) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `un_idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of users
-- ----------------------------
BEGIN;
INSERT INTO `users` VALUES (1, 'zhangsan', '0349a8cd4b237e190e6e4b471e214ef3','eC4mL7bZ5sN8');
INSERT INTO `users` VALUES (2, 'lisi', '4d7a330008c2191c4c76b9b3dd59841d','qN3fT4eK2yQ9');
COMMIT; -- ----------------------------
-- Table structure for user_roles
-- ----------------------------
DROP TABLE IF EXISTS `user_roles`;
CREATE TABLE `user_roles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL,
`role_name` varchar(64) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `un_idx_role_name` (`role_name`),
KEY `idx_username` (`username`),
KEY `idx_role_name` (`role_name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of user_roles
-- ----------------------------
BEGIN;
INSERT INTO `user_roles` VALUES (1, 'zhangsan', 'admin');
INSERT INTO `user_roles` VALUES (2, 'lisi', 'member');
COMMIT; -- ----------------------------
-- Table structure for roles_permissions
-- ----------------------------
DROP TABLE IF EXISTS `roles_permissions`;
CREATE TABLE `roles_permissions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_name` varchar(64) DEFAULT NULL,
`permission` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `un_idx_role_name_permission` (`role_name`,`permission`),
KEY `idx_role_name` (`role_name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of roles_permissions
-- ----------------------------
BEGIN;
INSERT INTO `roles_permissions` VALUES (2, 'admin', 'user:delete');
INSERT INTO `roles_permissions` VALUES (1, 'admin', 'user:update');
INSERT INTO `roles_permissions` VALUES (3, 'member', 'user:query');
COMMIT;

使用测试代码:

    /**
* 使用默认 JdbcRealm 中相关表进行相关登录认证、使用默认的sql语句进行授权
*/
@Test
public void testJdbcRealmByDefaultDBConfiguration() {
DefaultSecurityManager securityManager = new DefaultSecurityManager(); // #配置验证器
ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
// #配置策略
AtLeastOneSuccessfulStrategy authenticationStrategy = new AtLeastOneSuccessfulStrategy();
// #将验证器和策略关联起来
authenticator.setAuthenticationStrategy(authenticationStrategy);
securityManager.setAuthenticator(authenticator); // #授权器
ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
WildcardPermissionResolver permissionResolver = new WildcardPermissionResolver();
authorizer.setPermissionResolver(permissionResolver);
securityManager.setAuthorizer(authorizer); DruidDataSource dataSource = new DruidDataSource();
{
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setUrl(
"jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
} JdbcRealm jdbcRealm = new JdbcRealm();
jdbcRealm.setDataSource(dataSource);
// JdbcRealm.permissionsLookupEnabled 默认为false,必须设置为true才能进行角色的授权。
jdbcRealm.setPermissionsLookupEnabled(true); HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("MD5");
credentialsMatcher.setHashIterations(8);
jdbcRealm.setCredentialsMatcher(credentialsMatcher); securityManager.setRealms(Arrays.asList(jdbcRealm)); SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
subject.login(token);
System.out.println("是否通过认证:" + subject.isAuthenticated()); System.out.println("是否拥有admin角色:" + subject.hasRole("admin"));
// 必须设置JdbcRealm为jdbcRealm.setPermissionsLookupEnabled(true)
// 是否拥有修改的权限
System.out.println("是否拥有user:update角色:" + subject.isPermitted("user:update")); subject.logout();
System.out.println("是否通过认证:" + subject.isAuthenticated());
}

打印信息:

log4j:WARN No appenders could be found for logger (com.alibaba.druid.pool.DruidDataSource).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
是否通过认证:true
是否拥有admin角色:true
是否拥有user:update角色:true
是否通过认证:false

JdbcRealm使用自定义表和插叙SQL

需要在关系数据自定义三张表:my_user,my_role,my_permission。

-- ----------------------------
-- Table structure for my_user
-- ----------------------------
DROP TABLE IF EXISTS `my_user`;
CREATE TABLE `my_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL,
`password` varchar(64) NOT NULL,
`password_salt` varchar(64) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `un_idx_username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of my_user
-- ----------------------------
BEGIN;
INSERT INTO `my_user` VALUES (1, 'zhangsan', '0349a8cd4b237e190e6e4b471e214ef3','eC4mL7bZ5sN8');
INSERT INTO `my_user` VALUES (2, 'lisi', '4d7a330008c2191c4c76b9b3dd59841d','qN3fT4eK2yQ9');
COMMIT; -- ----------------------------
-- Table structure for my_role
-- ----------------------------
DROP TABLE IF EXISTS `my_role`;
CREATE TABLE `my_role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL,
`role_name` varchar(64) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `un_idx_role_name` (`role_name`) USING BTREE,
KEY `idx_username` (`username`),
KEY `idx_role_name` (`role_name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of my_role
-- ----------------------------
BEGIN;
INSERT INTO `my_role` VALUES (1, 'zhangsan', 'admin');
INSERT INTO `my_role` VALUES (2, 'lisi', 'member');
COMMIT;
-- ----------------------------
-- Table structure for my_permission
-- ----------------------------
DROP TABLE IF EXISTS `my_permission`;
CREATE TABLE `my_permission` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_name` varchar(64) DEFAULT NULL,
`permission` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `un_idx_role_name_permission` (`role_name`,`permission`) USING BTREE,
KEY `idx_role_name` (`role_name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of my_permission
-- ----------------------------
BEGIN;
INSERT INTO `my_permission` VALUES (2, 'admin', 'user:delete');
INSERT INTO `my_permission` VALUES (1, 'admin', 'user:update');
INSERT INTO `my_permission` VALUES (3, 'member', 'user:query');
COMMIT;

使用测试:

    @Test
public void testJdbcRealmByMyDBConfiguration() {
DruidDataSource dataSource = new DruidDataSource();
{
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setUrl(
"jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
} JdbcRealm jdbcRealm = new JdbcRealm();
jdbcRealm.setDataSource(dataSource);
// JdbcRealm.permissionsLookupEnabled 默认为false,必须设置为true才能进行角色的授权。
jdbcRealm.setPermissionsLookupEnabled(true);
jdbcRealm.setSaltStyle(SaltStyle.COLUMN); // 启用表 password_salt 字段 HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName("MD5");
credentialsMatcher.setHashIterations(8);
jdbcRealm.setCredentialsMatcher(credentialsMatcher); jdbcRealm.setAuthenticationQuery("select `password`,`password_salt` from `my_user` where `username`=? ");
jdbcRealm.setUserRolesQuery("select `role_name` from `my_role` where `username`=? ");
jdbcRealm.setPermissionsQuery("select `permission` from `my_permission` where role_name=? "); // 创建SecurityManager;
DefaultSecurityManager securityManager = new DefaultSecurityManager(jdbcRealm); SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject(); subject.logout();
UsernamePasswordToken token = new UsernamePasswordToken("lisi", "1234");
subject.login(token); System.out.println("是否通过认证:" + subject.isAuthenticated());
System.out.println("是否已经授权member角色:" + subject.hasRole("member"));
System.out.println("是否已经授权admin角色:" + subject.hasRole("admin")); System.out.println("是否已经拥有user:create资源:" + subject.isPermitted("user:create"));
System.out.println("是否已经拥有user:update资源:" + subject.isPermitted("user:update"));
System.out.println("是否已经拥有user:delete资源:" + subject.isPermitted("user:delete"));
System.out.println("是否已经拥有user:query资源:" + subject.isPermitted("user:query")); subject.logout();
System.out.println("是否通过认证:" + subject.isAuthenticated());
}

打印结果:

log4j:WARN No appenders could be found for logger (com.alibaba.druid.pool.DruidDataSource).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
是否通过认证:true
是否已经授权member角色:true
是否已经授权admin角色:false
是否已经拥有user:create资源:false
是否已经拥有user:update资源:false
是否已经拥有user:delete资源:false
是否已经拥有user:query资源:true
是否通过认证:false

Java-Shiro(五):Shiro Realm讲解(二)IniRealm的用法、JdbcRelam的用法、自定义Realm的更多相关文章

  1. Java NIO学习与记录(二):FileChannel与Buffer用法与说明

    FileChannel与Buffer用法与说明 上一篇简单介绍了NIO,这一篇将介绍FileChannel结合Buffer的用法,主要介绍Buffer FileChannel的简单使用&Buf ...

  2. java中的线程问题(二)——线程的创建和用法。

    在java中一个类要当作线程来使用有两种方法. 1.继承Thread类,并重写run函数 2.实现Runnable接口,并重写run函数 因为java是单继承的,在某些情况下一个类可能已经继承了某个父 ...

  3. Java 权限框架 Shiro 实战二:与spring集成、filter机制

    转自:https://www.cnblogs.com/digdeep/archive/2015/07/04/4620471.html Shiro和Spring的集成,涉及到很多相关的配置,涉及到shi ...

  4. shiro自定义realm认证(五)

    上一节介绍了realm的作用: realm:需要根据token中的身份信息去查询数据库(入门程序使用ini配置文件),如果查到用户返回认证信息,如果查询不到返回null.token就相当于是对用户输入 ...

  5. Shiro入门学习之自定义Realm实现授权(五)

    一.自定义Realm授权 前提:认证通过,查看Realm接口的继承关系结构图如下,要想通过自定义的Realm实现授权,只需继承AuthorizingRealm并重写方法即可 二.实现过程 1.新建mo ...

  6. shiro(二)自定义realm,模拟数据库查询验证

    自定义一个realm类,实现realm接口 package com; import org.apache.shiro.authc.*; import org.apache.shiro.realm.Re ...

  7. Shiro 核心功能案例讲解 基于SpringBoot 有源码

    Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...

  8. Apache shiro集群实现 (二) shiro 的INI配置

    Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...

  9. Shiro 安全框架详解二(概念+权限案例实现)

    Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...

随机推荐

  1. win10安装tensorflow (cpu版)

    前提: 下载anaconda,然后创建一个python虚拟环境: 命令: conda create -n tf_cpu python=3.6       # (tf_cpu  是这个虚拟环境的名字) ...

  2. DDOS常见攻击类型和防御措施

    DDOS 攻击类型: SYN Flood 攻击 ACK Flood 攻击 UDP Flood 攻击 ICMP Flood 攻击 Connection Flood 攻击 HTTP Get 攻击 UDP ...

  3. [转帖]DotNetCore跨平台~System.DrawingCore部署Linux需要注意的

    DotNetCore跨平台~System.DrawingCore部署Linux需要注意的   https://www.bbsmax.com/A/QV5ZemYVJy/?tdsourcetag=s_pc ...

  4. 基于 Vue.js 2.0 酷炫自适应背景视频登录页面的设计『转』

    本文讲述如何实现拥有酷炫背景视频的登录页面,浏览器窗口随意拉伸,背景视频及前景登录组件均能完美适配,背景视频可始终铺满窗口,前景组件始终居中,视频的内容始终得到最大限度的保留,可以得到最好的视觉效果. ...

  5. <<C++ Primer>> 第 6 章 函数

    术语表 第 6 章 函数 二义性调用(ambiguous call): 是一种编译时发生的错误,造成二义性调用的原因时在函数匹配时两个或多个函数提供的匹配一样好,编译器找不到唯一的最佳匹配.    实 ...

  6. Python之模块IO

    目录 Python之模块IO io概叙 io类层次结构 io模块的类图 io模块的3种I/O 原始I/O,即RawIOBase及其子类 文本I/O,即TextIOBase及其子类 字节I/O(缓存I/ ...

  7. USBIP源码分析

    简介 在普通的电脑上,想使用USB设备,必须将插入到主机.USBIP却可以通过网络,让主机访问其他主机上的外部设备,而用户程序完全感知不到区别. usbip的文章在这里:https://pdfs.se ...

  8. JS中的继承(下)

    JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...

  9. cSpring Boot整合RabbitMQ详细教程

    来自:https://blog.csdn.net/qq_38455201/article/details/80308771 十分详细,几张图片不显示,看这个地址 1.首先我们简单了解一下消息中间件的应 ...

  10. luogu P3320 [SDOI2015]寻宝游戏

    大意:给定树, 要求维护一个集合, 支持增删点, 询问从集合中任取一点作为起点, 遍历完其他点后原路返回的最短长度. 集合中的点按$dfs$序排列后, 最短距离就为$dis(s_1,s_2)+...+ ...