我是Spring的新世界,我正在使用带有Spring Security 3.1.2的Spring Boot 1.2.5。由于我的项目要求,我需要配置ACL安全模型。我有以下java类配置:
@Configuration
public class ACLConfig {
@Autowired
DataSource dataSource;
@Bean
JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource);
}
@Bean
DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource);
}
@Bean
EhCacheBasedAclCache aclCache() {
EhCacheFactoryBean factoryBean = new EhCacheFactoryBean();
EhCacheManagerFactoryBean cacheManager = new EhCacheManagerFactoryBean();
cacheManager.setAcceptExisting(true);
cacheManager.setCacheManagerName(CacheManager.getInstance().getName());
cacheManager.afterPropertiesSet();
factoryBean.setName("aclCache");
factoryBean.setCacheManager(cacheManager.getObject());
factoryBean.setMaxBytesLocalHeap("16M");
factoryBean.setMaxEntriesLocalHeap(0L);
factoryBean.afterPropertiesSet();
return new EhCacheBasedAclCache(factoryBean.getObject());
}
@Bean
LookupStrategy lookupStrategy() {
return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger());
}
@Bean
AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_SUPER_ADMIN"),
new SimpleGrantedAuthority("ROLE_SUPER_ADMIN"),
new SimpleGrantedAuthority("ROLE_SUPER_ADMIN"));
}
@Bean
JdbcMutableAclService aclService() {
JdbcMutableAclService service = new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache());
service.setClassIdentityQuery("select currval(pg_get_serial_sequence('acl_class', 'id'))");
service.setSidIdentityQuery("select currval(pg_get_serial_sequence('acl_sid', 'id'))");
return service;
}
@Bean
AclEntryVoter aclDeleteVoter()
{
AclEntryVoter voter = new AclEntryVoter(aclService(),"ACL_NOMCITY_DELETE", new Permission[] {BasePermission.DELETE});
voter.setProcessDomainObjectClass(NomCity.class);
return voter;
}
@Bean
AclEntryVoter aclUpdateVoter()
{
return new AclEntryVoter(aclService(),"ACL_NOMCITY_UPDATE", new Permission[]{BasePermission.ADMINISTRATION});
}
@Bean
AclEntryVoter aclReadVoter()
{
return new AclEntryVoter(aclService(),"ACL_NOMCITY_READ", new Permission[]{BasePermission.READ});
}
@Bean
AccessDecisionManager accessDecisionManager (){
List<AccessDecisionVoter<? extends Object>> list = new ArrayList<>();
list.add(aclDeleteVoter());
list.add(aclReadVoter());
list.add(aclUpdateVoter());
return new AffirmativeBased(list);
}
}
我有以下RestController的方法,它使用前面定义的ACL:
@RequestMapping(value = "/nomCitys",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@Transactional
@Secured({"ROLE_ADMIN","ROLE_USER"})
public ResponseEntity<NomCity> create(@Valid @RequestBody NomCity nomCity) throws URISyntaxException {
NomCity result = nomCityRepository.save(nomCity);
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
ObjectIdentity oi = new ObjectIdentityImpl(NomCity.class,result.hashCode());
MutableAcl acl = mutableAclService.createAcl(oi);
acl.insertAce(0, BasePermission.ADMINISTRATION, new GrantedAuthoritySid("ROLE_ADMIN"), true);
acl.insertAce(1, BasePermission.DELETE, new PrincipalSid(user.getUsername()), true);
acl.insertAce(2, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER"), true);
mutableAclService.updateAcl(acl);
return ResponseEntity.created(new URI("/api/nomCitys/" + result.getId()))
.headers(HeaderUtil.createEntityCreationAlert("nomCity", result.getId().toString()))
.body(result);
}
创建新城市时,也会创建以下ACL条目:
以下方法是删除方法:
@RequestMapping(value = "/nomCitys/{id}",
method = RequestMethod.DELETE,
produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@Transactional
@Secured("ACL_NOMCITY_DELETE")
public ResponseEntity<Void> delete(@PathVariable Long id) {
nomCityRepository.delete(id);
ObjectIdentity oid = new ObjectIdentityImpl(NomCity.class,id);
mutableAclService.deleteAcl(oid, true);
return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert("nomCity", id.toString())).build();
}
当我创建一个新的城市一切正常时,ACL条目被创建并存储在数据库中,但当我去删除一个城市时,我得到403,尽管我正在与创建城市的用户一起登录,查看我看到以下xml条目的一些页面:
<security:global-method-security
secured-annotations="enabled" access-decision-manager ref="customAccessDecisionManager" />
我想它注册了AccessDecisionManager,但是我不知道如何使用Java Config,如果这是我所有问题的原因,我不知道。
答案 0 :(得分:0)
这个问题适用于@secure anotation,但是我终于解决了使用@Pre和@Post anotation进行类配置的问题,我在这个question的答案中发布了一个配置java类。