如上所述,ACL 是一种选择,但另一种可能更简单的解决方案可能是在方法级别应用安全性。
请参阅第 15.3 节。
https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html
因此,假设您有一个 URL /users/123,其中 123 是当前用户,它委托给服务层方法来加载用户,那么我该如何防止用户篡改 URL 并查看 /users/456 等返回的数据.
一种方法是通过 @PostAuthorize 注释应用方法级别的安全性:
@PostAuthorize("hasPermission(returnObject, null)")
public User findById(Long id) {
return repository.findOne(id);
}
安全检查委托给 org.springframework.security.access.PermissionEvaluator 的实现
一个实现可能如下所示:
public class BasePermissionsEvaluator implements PermissionEvaluator {
public boolean hasPermission(Authentication authentication, Object domainObject) {
return hasPermission(authentication, domainObject, null);
}
@Override
public boolean hasPermission(Authentication authentication, Object domainObject, Object permission) {
boolean hasPermission = true;
//User is my custom class representing a logged in user
//UserEntity is my custom interface implemented by entities associated with specific user
//If user is an Admin allow access
//Otherwise allow access if logged in user 'owns' the DomainObject instance
User user = (User) authentication.getPrincipal();
if(! user.isAdmin()){
if (domainObject instanceof UserEntity) {
User owner = ((UserEntity) domainObject).getOwner();
hasPermission = user.equals(owner);
}
}
return hasPermission;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
Object permission) {
return false;
}
}
PermissionEvaluator 的配置在 XML 中如下所示,因此您需要转换为 Java 配置:
<security:global-method-security
pre-post-annotations="enabled">
<security:expression-handler ref="expressionHandler"/>
</security:global-method-security>
<bean id="expressionHandler"
class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<property name="permissionEvaluator" ref="permissionEvaluator" />
</bean>
<bean id="permissionEvaluator" class="com.mycompany.BasePermissionsEvaluator" />
以下概述了将 XML 配置转换为 Java 配置:
https://spring.io/blog/2013/07/04/spring-security-java-config-preview-method-security/#custom-method-security
因此,在您现有的安全配置类中,您似乎会添加:
@EnableGlobalMethodSecurity(prePostEnabled=true) //ADD THIS
public class MySecurityConfig{
@Override
protected MethodSecurityExpressionHandler expressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
//SET TO OUR CUSTOM PERMISSIONS HANDLER DETAILED ABOVE
expressionHandler.setPermissionEvaluator(new BasePermissionsEvaluator());
return expressionHandler;
}
}