@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class AclConfig {
@Autowired
DataSource dataSource;
@Bean
public AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority(“ROLE_ADMIN”));
}
@Bean
public PermissionGrantingStrategy permissionGrantingStrategy() {
return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());
}
@Bean
public AclCache aclCache() {
return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(), permissionGrantingStrategy(), aclAuthorizationStrategy());
}
@Bean
public EhCacheFactoryBean aclEhCacheFactoryBean() {
EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean();
ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject());
ehCacheFactoryBean.setCacheName(“aclCache”);
return ehCacheFactoryBean;
}
@Bean
public EhCacheManagerFactoryBean aclCacheManager() {
return new EhCacheManagerFactoryBean();
}
@Bean
public LookupStrategy lookupStrategy() {
return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger()
);
}
@Bean
public AclService aclService() {
return new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache());
}
@Bean
PermissionEvaluator permissionEvaluator() {
AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService());
return permissionEvaluator;
}
}
-
@EnableGlobalMethodSecurity 注解的配置表示开启项目中 @PreAuthorize、@PostAuthorize 以及 @Secured 注解的使用,一会我们要通过这些注解配置权限。
-
由于引入了数据库的一整套东西,并且配置了数据库连接信息,所以这里可以注入 DataSource 实例以备后续使用。
-
AclAuthorizationStrategy 实例用来判断当前的认证主体是否有修改 Acl 的权限,准确来说是三种权限:修改 Acl 的 owner;修改 Acl 的审计信息以及修改 ACE 本身。这个接口只有一个实现类就是 AclAuthorizationStrategyImpl,我们在创建实例时,可以传入三个参数,分别对应了这三种权限,也可以传入一个参数,表示这一个角色可以干三件事。
-
PermissionGrantingStrategy 接口提供了一个 isGranted 方法,这个方法就是最终真正进行权限比对的方法,该接口只有一个实现类 DefaultPermissionGrantingStrategy,直接 new 就行了。
-
在 ACL 体系中,由于权限比对总是要查询数据库,造成了性能问题,因此引入了 Ehcache 做缓存。AclCache 共有两个实现类:SpringCacheBasedAclCache 和 EhCacheBasedAclCache。我们前面已经引入了 ehcache 实例,所以这里配置 EhCacheBasedAclCache 实例即可。
-
LookupStrategy 可以通过 ObjectIdentity 解析出对应的 Acl。LookupStrategy 只有一个实现类就是 BasicLookupStrategy,直接 new 即可。
-
AclService 这个我们在上文已经介绍过了,这里不再赘述。
-
PermissionEvaluator 是为表达式 hasPermission 提供支持的。由于本案例后面使用类似于
@PreAuthorize("hasPermission(#noticeMessage, 'WRITE')")
这样的注解进行权限控制,因此之类需要配置一个 PermissionEvaluator 实例。
至此,这里的配置类就和大家介绍完了。
假设我现在有一个通知消息类 NoticeMessage,如下:
public class NoticeMessage {
private Integer id;
private String content;
@Override
public String toString() {
return “NoticeMessage{” +
“id=” + id +
“, content='” + content + ‘’’ +
‘}’;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
然后根据该类创建了数据表:
CREATE TABLE system_message
(
id
int(11) unsigned NOT NULL AUTO_INCREMENT,
content
varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
那么接下来的权限控制就是针对这个 NoticeMessage 的。
创建 NoticeMessageMapper,并添加几个测试方法:
@Mapper
public interface NoticeMessageMapper {
List findAll();
NoticeMessage findById(Integer id);
void save(NoticeMessage noticeMessage);
void update(NoticeMessage noticeMessage);
}
NoticeMessageMapper.xml 内容如下:
select * from system_message;
select * from system_message where id=#{id};
insert into system_message (id,content) values (#{id},#{content});
update system_message set content = #{content} where id=#{id};
这些应该都好理解,没啥好说的。
接下来创建 NoticeMessageService,如下:
@Service
public class NoticeMessageService {
@Autowired
NoticeMessageMapper noticeMessageMapper;
@PostFilter(“hasPermission(filterObject, ‘READ’)”)
public List findAll() {
List all = noticeMessageMapper.findAll();
return all;
}
@PostAuthorize(“hasPermission(returnObject, ‘READ’)”)
public NoticeMessage findById(Integer id) {
return noticeMessageMapper.findById(id);
}
@PreAuthorize(“hasPermission(#noticeMessage, ‘CREATE’)”)
public NoticeMessage save(NoticeMessage noticeMessage) {
noticeMessageMapper.save(noticeMessage);
return noticeMessage;
}
@PreAuthorize(“hasPermission(#noticeMessage, ‘WRITE’)”)
public void update(NoticeMessage noticeMessage) {
noticeMessageMapper.update(noticeMessage);
}
}
涉及到了两个新注解,稍微说下:
-
@PostFilter:在执行方法后过滤返回的集合或数组(筛选出当前用户具有 READ 权限的数据),returnObject 就表示方法的返回值。有一个和它对应的注解 @PreFilter,这个注解允许方法调用,但必须在进入方法之前对参数进行过滤。
-
@PostAuthorize:允许方法调用,但是如果表达式计算结果为false,将抛出一个安全性异常,
#noticeMessage
对应了方法的参数。 -
@PreAuthorize:在方法调用之前,基于表达式的计算结果来限制对方法的访问。
明白了注解的含义,那么上面的方法应该就不用多做解释了吧。
配置完成,接下来我们进行测试。
为了方便测试,我们首先准备几条测试数据,如下:
INSERT INTO acl_class
(id
, class
)
VALUES
(1,‘org.javaboy.acls.model.NoticeMessage’);
INSERT INTO acl_sid
(id
, principal
, sid
)
VALUES
(2,1,‘hr’),
(1,1,‘manager’),
(3,0,‘ROLE_EDITOR’);
INSERT INTO system_message
(id
, content
)
VALUES
(1,‘111’),
(2,‘222’),
(3,‘333’);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
《MySql面试专题》
《MySql性能优化的21个最佳实践》
《MySQL高级知识笔记》
文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图
关注我,点赞本文给更多有需要的人
[外链图片转存中…(img-6G5PJ4A2-1711812249789)]
[外链图片转存中…(img-116QMizF-1711812249789)]
[外链图片转存中…(img-YTLxQjzh-1711812249790)]
[外链图片转存中…(img-zNEDIJF4-1711812249790)]
[外链图片转存中…(img-prgPP1YB-1711812249790)]
[外链图片转存中…(img-y6btA5je-1711812249791)]
[外链图片转存中…(img-DGYPTKfu-1711812249791)]
[外链图片转存中…(img-UcAT14Nr-1711812249791)]
文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图
[外链图片转存中…(img-Ons1UMNN-1711812249791)]
关注我,点赞本文给更多有需要的人