Skip to content

Commit

Permalink
Add ability to provide additional resource context fields
Browse files Browse the repository at this point in the history
in Check middleware.
  • Loading branch information
ronenh committed Oct 15, 2024
1 parent fca24ec commit fcb1b70
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
@SpringBootApplication
@ComponentScan("com.aserto")
public class JavaApplication {
public static void main(String[] args) {
SpringApplication.run(JavaApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(JavaApplication.class, args);
}

}
156 changes: 138 additions & 18 deletions src/main/java/com/aserto/authorizer/CheckConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,158 @@
import com.aserto.authorizer.mapper.policy.PolicyMapper;
import com.aserto.authorizer.mapper.policy.StaticPolicyMapper;
import com.aserto.authorizer.mapper.resource.CheckResourceMapper;
import com.aserto.authorizer.mapper.resource.EmptyResourceMapper;
import com.aserto.authorizer.mapper.resource.ResourceMapper;

public class CheckConfig {
private AuthzConfig authzCfg;
private final AuthzConfig authzCfg;

private ObjectTypeMapper objectTypeMapper;
private ObjectIdMapper objectIdMapper;
private RelationMapper relationMapper;
private PolicyMapper policyMapper;
private final ObjectTypeMapper objectTypeMapper;
private final ObjectIdMapper objectIdMapper;
private final RelationMapper relationMapper;
private final PolicyMapper policyMapper;
/**
* ResourceMapper for additional fields to be included in the resource context.
*/
private final ResourceMapper baseResourceMapper;

public CheckConfig(AuthzConfig authzCfg) {
// Clone the authz config because we will change it
this.authzCfg = new AuthzConfig(authzCfg);
static final String DEFAULT_POLICY = "rebac.check";

public CheckConfig(
AuthzConfig filterConfig,
String objectType,
String objectID,
String relation
) {
this(filterConfig, objectType, objectID, relation, DEFAULT_POLICY);
}

public CheckConfig(AuthzConfig filterConfig, String objectType, String objectID, String relation) {
this(filterConfig, objectType, objectID, relation, "rebac.check");
public CheckConfig(
AuthzConfig filterConfig,
String objectType,
String objectID,
String relation,
String policy
) {
this(filterConfig, objectType, objectID, relation, policy, new EmptyResourceMapper());
}

public CheckConfig(AuthzConfig filterConfig, String objectType, String objectID, String relation, String policy) {
this(filterConfig, new StaticObjectTypeMapper(objectType), new StaticObjectIdMapper(objectID), new StaticRelationMapper(relation), new StaticPolicyMapper(policy));
}
public CheckConfig(
AuthzConfig filterConfig,
String objectType,
String objectID,
String relation,
ResourceMapper baseResourceMapper
) {
this(filterConfig, objectType, objectID, relation, DEFAULT_POLICY, baseResourceMapper);
}

public CheckConfig(
AuthzConfig filterConfig,
String objectType,
String objectID,
String relation,
String policy,
ResourceMapper baseResourceMapper
) {
this(
filterConfig,
new StaticObjectTypeMapper(objectType),
new StaticObjectIdMapper(objectID),
new StaticRelationMapper(relation),
new StaticPolicyMapper(policy),
baseResourceMapper
);
}

public CheckConfig(AuthzConfig filterConfig, String objectType, ObjectIdMapper objectIdMapper, String relation) {
this(filterConfig, objectType, objectIdMapper, relation, DEFAULT_POLICY);
}

public CheckConfig(AuthzConfig filterConfig, String objectType, ObjectIdMapper objectIdMapper, String relation, String policy) {
this(
filterConfig,
new StaticObjectTypeMapper(objectType),
objectIdMapper,
new StaticRelationMapper(relation),
new StaticPolicyMapper(policy),
new EmptyResourceMapper()
);
}

public CheckConfig(
AuthzConfig filterConfig,
String objectType,
ObjectIdMapper objectIdMapper,
String relation,
ResourceMapper baseResourceMapper
) {
this(
filterConfig,
new StaticObjectTypeMapper(objectType),
objectIdMapper,
new StaticRelationMapper(relation),
new StaticPolicyMapper(DEFAULT_POLICY),
new EmptyResourceMapper()
);
}

public CheckConfig(
AuthzConfig filterConfig,
String objectType,
ObjectIdMapper objectIdMapper,
String relation,
String policy,
ResourceMapper baseResourceMapper
) {
this(
filterConfig,
new StaticObjectTypeMapper(objectType),
objectIdMapper,
new StaticRelationMapper(relation),
new StaticPolicyMapper(policy),
baseResourceMapper
);
}

public CheckConfig(AuthzConfig filterConfig, ObjectTypeMapper objectTypeMapper, ObjectIdMapper objectIdMapper, RelationMapper relationMapper) {
this(filterConfig, objectTypeMapper, objectIdMapper, relationMapper, new StaticPolicyMapper("rebac.check"));
}
this(filterConfig, objectTypeMapper, objectIdMapper, relationMapper, new StaticPolicyMapper(DEFAULT_POLICY));
}

public CheckConfig(
AuthzConfig filterConfig,
ObjectTypeMapper objectTypeMapper,
ObjectIdMapper objectIdMapper,
RelationMapper relationMapper,
PolicyMapper policyMapper
) {
this(filterConfig, objectTypeMapper, objectIdMapper, relationMapper, policyMapper, new EmptyResourceMapper());
}

public CheckConfig(
AuthzConfig filterConfig,
ObjectTypeMapper objectTypeMapper,
ObjectIdMapper objectIdMapper,
RelationMapper relationMapper,
ResourceMapper baseResourceMapper
) {
this(filterConfig, objectTypeMapper, objectIdMapper, relationMapper, new StaticPolicyMapper(DEFAULT_POLICY), new EmptyResourceMapper());
}

public CheckConfig(AuthzConfig filterConfig, ObjectTypeMapper objectTypeMapper, ObjectIdMapper objectIdMapper, RelationMapper relationMapper, PolicyMapper policyMapper) {
public CheckConfig(
AuthzConfig filterConfig,
ObjectTypeMapper objectTypeMapper,
ObjectIdMapper objectIdMapper,
RelationMapper relationMapper,
PolicyMapper policyMapper,
ResourceMapper baseResourceMapper
) {
this.authzCfg = new AuthzConfig(filterConfig);
this.objectTypeMapper = objectTypeMapper;
this.objectIdMapper = objectIdMapper;
this.relationMapper = relationMapper;
this.policyMapper = policyMapper;
this.policyMapper = policyMapper;
this.baseResourceMapper = baseResourceMapper != null ? baseResourceMapper : new EmptyResourceMapper();
}

public AsertoAuthorizationManager getAuthManager() {
Expand All @@ -49,7 +169,7 @@ public AsertoAuthorizationManager getAuthManager() {

public AuthzConfig getConfig() {
authzCfg.setPolicyMapper(policyMapper);
authzCfg.setResourceMapper(new CheckResourceMapper(objectTypeMapper, objectIdMapper, relationMapper));
authzCfg.setResourceMapper(new CheckResourceMapper(objectTypeMapper, objectIdMapper, relationMapper, baseResourceMapper));

return authzCfg;
}
Expand Down
28 changes: 22 additions & 6 deletions src/main/java/com/aserto/authorizer/MethodAuthorization.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.aserto.authorizer;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.stereotype.Component;

Expand All @@ -18,26 +17,32 @@
import com.aserto.authorizer.mapper.policy.PolicyMapper;
import com.aserto.authorizer.mapper.policy.StaticPolicyMapper;
import com.aserto.authorizer.mapper.resource.CheckResourceMapper;
import com.aserto.authorizer.mapper.resource.EmptyResourceMapper;
import com.aserto.authorizer.mapper.resource.ResourceMapper;

import jakarta.servlet.http.HttpServletRequest;

/*
* This class provides methods to check if the current user is authorized to perform an action.
* It can be used for method level authorization.
*/
@Component("check")
class MethodAuthorization {
private AsertoAuthorizationManager asertoAuthzManager;
private HttpServletRequest httpRequest;
private final AsertoAuthorizationManager asertoAuthzManager;
private final HttpServletRequest httpRequest;
private ObjectTypeMapper objectTypeMapper;
private ObjectIdMapper objectIdMapper;
private RelationMapper relationMapper;
private SubjectTypeMapper subjectTypeMapper;
private SubjectIdMapper subjectIdMapper;
private PolicyMapper policyMapper;
private PolicyMapper policyMapper;
private ResourceMapper baseResourceMapper;

public MethodAuthorization(AuthzConfig authzCfg, HttpServletRequest httpRequest) {
asertoAuthzManager = new AsertoAuthorizationManager(authzCfg);
this.httpRequest = httpRequest;
this.policyMapper = new StaticPolicyMapper("rebac.check");
this.policyMapper = new StaticPolicyMapper("rebac.check");
this.baseResourceMapper = new EmptyResourceMapper();
}

public MethodAuthorization objectType(String objectType) {
Expand Down Expand Up @@ -100,10 +105,21 @@ public MethodAuthorization policyMapper(PolicyMapper policyMapper) {
return this;
}

public MethodAuthorization baseResourceMapper(ResourceMapper baseResourceMapper) {
this.baseResourceMapper = baseResourceMapper;
return this;
}

public boolean allowed() {
validateFields();

CheckResourceMapper checkResourceMapper = new CheckResourceMapper(objectTypeMapper, objectIdMapper, relationMapper, subjectTypeMapper);
CheckResourceMapper checkResourceMapper = new CheckResourceMapper(
objectTypeMapper,
objectIdMapper,
relationMapper,
subjectTypeMapper,
baseResourceMapper
);

AuthorizationDecision decision;
if (subjectIdMapper != null && subjectTypeMapper != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,47 +1,70 @@
package com.aserto.authorizer.mapper.resource;

import java.util.Map;

import com.aserto.authorizer.mapper.check.object.ObjectIdMapper;
import com.aserto.authorizer.mapper.check.object.ObjectTypeMapper;
import com.aserto.authorizer.mapper.check.object.StaticObjectIdMapper;
import com.aserto.authorizer.mapper.check.object.StaticObjectTypeMapper;
import com.aserto.authorizer.mapper.check.relation.RelationMapper;
import com.aserto.authorizer.mapper.check.relation.StaticRelationMapper;
import com.aserto.authorizer.mapper.check.subject.StaticSubjectTypeMapper;
import com.aserto.authorizer.mapper.check.subject.SubjectTypeMapper;
import com.google.protobuf.Value;
import jakarta.servlet.http.HttpServletRequest;

import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;

public class CheckResourceMapper implements ResourceMapper {
private ObjectTypeMapper objectTypeMapper;
private ObjectIdMapper objectIdMapper;
private RelationMapper relationMapper;

private SubjectTypeMapper subjectTypeMapper;
private final ObjectTypeMapper objectTypeMapper;
private final ObjectIdMapper objectIdMapper;
private final RelationMapper relationMapper;
private final SubjectTypeMapper subjectTypeMapper;
private final ResourceMapper baseResourceMapper;

public CheckResourceMapper(String objectType, String objectId, String relation) {
this.objectTypeMapper = new StaticObjectTypeMapper(objectType);
this.objectIdMapper = new StaticObjectIdMapper(objectId);
this.relationMapper = new StaticRelationMapper(relation);
this(new StaticObjectTypeMapper(objectType),new StaticObjectIdMapper(objectId), new StaticRelationMapper(relation));
}

public CheckResourceMapper(String objectType, String objectId, String relation, String subjectType) {
this(
new StaticObjectTypeMapper(objectType),
new StaticObjectIdMapper(objectId),
new StaticRelationMapper(relation),
new StaticSubjectTypeMapper(subjectType),
new EmptyResourceMapper()
);
}

public CheckResourceMapper(ObjectTypeMapper objectTypeMapper, ObjectIdMapper objectIdMapper, RelationMapper relationMapper) {
this.objectTypeMapper = objectTypeMapper;
this.objectIdMapper = objectIdMapper;
this.relationMapper = relationMapper;
this(objectTypeMapper, objectIdMapper, relationMapper, null, new EmptyResourceMapper());
}

public CheckResourceMapper(
ObjectTypeMapper objectTypeMapper,
ObjectIdMapper objectIdMapper,
RelationMapper relationMapper,
ResourceMapper baseResourceMapper
) {
this(objectTypeMapper, objectIdMapper, relationMapper, null, baseResourceMapper);
}

public CheckResourceMapper(ObjectTypeMapper objectTypeMapper, ObjectIdMapper objectIdMapper, RelationMapper relationMapper, SubjectTypeMapper subjectTypeMapper) {
public CheckResourceMapper(
ObjectTypeMapper objectTypeMapper,
ObjectIdMapper objectIdMapper,
RelationMapper relationMapper,
SubjectTypeMapper subjectTypeMapper,
ResourceMapper baseResourceMapper
) {
this.objectTypeMapper = objectTypeMapper;
this.objectIdMapper = objectIdMapper;
this.relationMapper = relationMapper;
this.subjectTypeMapper = subjectTypeMapper;
this.baseResourceMapper = baseResourceMapper != null ? baseResourceMapper : new EmptyResourceMapper();
}

@Override
public Map<String, Value> getResource(HttpServletRequest request) throws ResourceMapperError {
Map<String, Value> resourceCtx = new HashMap<>();
Map<String, Value> resourceCtx = baseResourceMapper.getResource(request);
resourceCtx.put("object_type", Value.newBuilder().setStringValue(objectTypeMapper.getValue(request)).build());
resourceCtx.put("object_id", Value.newBuilder().setStringValue(objectIdMapper.getValue(request)).build());
resourceCtx.put("relation", Value.newBuilder().setStringValue(relationMapper.getValue(request)).build());
Expand Down
Loading

0 comments on commit fcb1b70

Please sign in to comment.