Java-Shiro(五):Shiro Realm讲解(二)IniRealm的用法、JdbcRelam的用法、自定义Realm
引入
上一篇在讲解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的更多相关文章
- Java NIO学习与记录(二):FileChannel与Buffer用法与说明
FileChannel与Buffer用法与说明 上一篇简单介绍了NIO,这一篇将介绍FileChannel结合Buffer的用法,主要介绍Buffer FileChannel的简单使用&Buf ...
- java中的线程问题(二)——线程的创建和用法。
在java中一个类要当作线程来使用有两种方法. 1.继承Thread类,并重写run函数 2.实现Runnable接口,并重写run函数 因为java是单继承的,在某些情况下一个类可能已经继承了某个父 ...
- Java 权限框架 Shiro 实战二:与spring集成、filter机制
转自:https://www.cnblogs.com/digdeep/archive/2015/07/04/4620471.html Shiro和Spring的集成,涉及到很多相关的配置,涉及到shi ...
- shiro自定义realm认证(五)
上一节介绍了realm的作用: realm:需要根据token中的身份信息去查询数据库(入门程序使用ini配置文件),如果查到用户返回认证信息,如果查询不到返回null.token就相当于是对用户输入 ...
- Shiro入门学习之自定义Realm实现授权(五)
一.自定义Realm授权 前提:认证通过,查看Realm接口的继承关系结构图如下,要想通过自定义的Realm实现授权,只需继承AuthorizingRealm并重写方法即可 二.实现过程 1.新建mo ...
- shiro(二)自定义realm,模拟数据库查询验证
自定义一个realm类,实现realm接口 package com; import org.apache.shiro.authc.*; import org.apache.shiro.realm.Re ...
- Shiro 核心功能案例讲解 基于SpringBoot 有源码
Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...
- Apache shiro集群实现 (二) shiro 的INI配置
Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...
- Shiro 安全框架详解二(概念+权限案例实现)
Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...
随机推荐
- JAVA -数据类型与表达式---数据类型转换
数据类型转换技术 Java中,数据转换的方式有三种:*赋值类型转换*提升类型转换*强制类型转换 1.赋值类型转换 当需要将一个类型的值赋给另一种类型的变量时,该值将被转换为新类型的值,此时就发生了赋值 ...
- php导出excel方法: 所有语言通用
后端: //导出if($_GPC['export']==1){ $list_export = pdo_fetchall($sql.$where); include $this->templa ...
- xshell设置
登录脚本: #定义rz,sz自动下载路径 #保持窗口活动状态, 空闲时每120秒发送一个回车
- python学习笔记四 (运算符重载和命名空间、类)
从以上代码中应该了解到: obj.attribute 查找的顺序: 从对象,类组成的树中,从下到上,从左到右到查找最近到attribute属性值,因为rec中存在name的属性,所以x.name可以 ...
- MY TESTS
励志整理所有的n次考试的博客: [五一qbxt]test1 [五一qbxt]test2 [校内test]桶哥的问题 [6.10校内test] noip模拟 6.12校内test [6.12校内test ...
- jinja2 模板相关
安装 pip install jinja2 配置模板 settings.py 60行左右 TEMPLATES = [ { 'BACKEND': 'django.template.backends.dj ...
- 学习python基础规则
前面应该是记流水账的方式,毕竟学习的内容不多无法产出什么有效的内容. 这两天从开始下载Python开始学习,一路顺畅冒的问题,直到开始学习python的游戏规则,严格缩进.注释及‘’的使用等感觉还不错 ...
- spark教程(14)-共享变量
spark 使用的架构是无共享的,数据分布在不同节点,每个节点有独立的 CPU.内存,不存在全局的内存使得变量能够共享,驱动程序和任务之间通过消息共享数据 举例来说,如果一个 RDD 操作使用了驱动程 ...
- 实现Promise类
基本使用: let promise = new Promise((resolve, reject) => { // do something if (true) { resolve('succe ...
- JS基础_数据类型-Boolean类型
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...