一个案例演示 Spring Security 中粒度超细的权限控制!

@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;

}

}

  1. @EnableGlobalMethodSecurity 注解的配置表示开启项目中 @PreAuthorize、@PostAuthorize 以及 @Secured 注解的使用,一会我们要通过这些注解配置权限。

  2. 由于引入了数据库的一整套东西,并且配置了数据库连接信息,所以这里可以注入 DataSource 实例以备后续使用。

  3. AclAuthorizationStrategy 实例用来判断当前的认证主体是否有修改 Acl 的权限,准确来说是三种权限:修改 Acl 的 owner;修改 Acl 的审计信息以及修改 ACE 本身。这个接口只有一个实现类就是 AclAuthorizationStrategyImpl,我们在创建实例时,可以传入三个参数,分别对应了这三种权限,也可以传入一个参数,表示这一个角色可以干三件事。

  4. PermissionGrantingStrategy 接口提供了一个 isGranted 方法,这个方法就是最终真正进行权限比对的方法,该接口只有一个实现类 DefaultPermissionGrantingStrategy,直接 new 就行了。

  5. 在 ACL 体系中,由于权限比对总是要查询数据库,造成了性能问题,因此引入了 Ehcache 做缓存。AclCache 共有两个实现类:SpringCacheBasedAclCache 和 EhCacheBasedAclCache。我们前面已经引入了 ehcache 实例,所以这里配置 EhCacheBasedAclCache 实例即可。

  6. LookupStrategy 可以通过 ObjectIdentity 解析出对应的 Acl。LookupStrategy 只有一个实现类就是 BasicLookupStrategy,直接 new 即可。

  7. AclService 这个我们在上文已经介绍过了,这里不再赘述。

  8. PermissionEvaluator 是为表达式 hasPermission 提供支持的。由于本案例后面使用类似于 @PreAuthorize("hasPermission(#noticeMessage, 'WRITE')") 这样的注解进行权限控制,因此之类需要配置一个 PermissionEvaluator 实例。

至此,这里的配置类就和大家介绍完了。

3.情节设定


假设我现在有一个通知消息类 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:在方法调用之前,基于表达式的计算结果来限制对方法的访问。

明白了注解的含义,那么上面的方法应该就不用多做解释了吧。

配置完成,接下来我们进行测试。

4.测试


为了方便测试,我们首先准备几条测试数据,如下:

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开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

《MySql面试专题》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

《MySql性能优化的21个最佳实践》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

《MySQL高级知识笔记》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

关注我,点赞本文给更多有需要的人

[外链图片转存中…(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)]

关注我,点赞本文给更多有需要的人

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值