Skip to content

Commit

Permalink
Policy validator configurable per endpoint in config
Browse files Browse the repository at this point in the history
Signed-off-by: David Kral <[email protected]>
  • Loading branch information
Verdent committed Sep 12, 2024
1 parent 5134b93 commit 8211076
Show file tree
Hide file tree
Showing 19 changed files with 817 additions and 193 deletions.
40 changes: 29 additions & 11 deletions docs/src/main/asciidoc/includes/security/providers/abac.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,11 @@ Annotations: `@RolesAllowed`, `@RoleValidator.Roles`
.Configuration example for `WebServer`
----
security:
web-server.paths:
- path: "/user[/{*}]"
roles-allowed: ["user"]
features:
security:
paths:
- path: "/user[/{*}]"
roles-allowed: ["user"]
----
[source,java]
Expand Down Expand Up @@ -160,10 +162,12 @@ Annotations: `@Scope`
.Configuration example for `WebServer`
----
security:
web-server.paths:
- path: "/user[/{*}]"
abac.scopes:
["calendar_read", "calendar_edit"]
features:
security:
paths:
- path: "/user[/{*}]"
abac.scopes:
["calendar_read", "calendar_edit"]
----
[source,java]
Expand All @@ -185,14 +189,28 @@ Example of a policy statement: `${env.time.year >= 2017}`
.Configuration example for `WebServer`
----
security:
web-server.paths:
- path: "/user[/{*}]"
policy:
statement: "hasScopes('calendar_read','calendar_edit') AND timeOfDayBetween('8:15', '17:30')"
features:
security:
paths:
- path: "/user[/{*}]"
policy:
statement: "hasScopes('calendar_read','calendar_edit') AND timeOfDayBetween('8:15', '17:30')"
----
[source,java]
.JAX-RS example
----
include::{sourcedir}/includes/security/providers/AbacSnippets.java[tag=snippet_4, indent=0]
----
[source,yaml]
.Configuration example for `JAX-RS` over the configuration
----
security:
features:
security:
endpoints:
- path: "/somePath"
config:
abac.policy-validator.statement: "${env.time.year >= 2017}"
----
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023 Oracle and/or its affiliates.
* Copyright (c) 2018, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,7 +36,7 @@ public Principal getUserPrincipal() {

@Override
public boolean isUserInRole(String role) {
return securityContext.isUserInRole(role, methodSecurity.getAuthorizer());
return securityContext.isUserInRole(role, methodSecurity.authorizer());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import java.util.Map;

import io.helidon.common.config.Config;
import io.helidon.security.AuditEvent;
import io.helidon.security.SecurityLevel;
import io.helidon.security.annotations.Audited;
Expand Down Expand Up @@ -96,8 +97,22 @@ SecurityDefinition copyMe() {

return result;
}

void fromConfig(Config config) {
config.get("authorize").as(Boolean.class).ifPresent(this::requiresAuthorization);
config.get("authorizer").as(String.class).ifPresent(this::authorizer);
config.get("authorization-explicit").as(Boolean.class).ifPresent(this::atzExplicit);
config.get("authenticate").as(Boolean.class).ifPresent(this::requiresAuthentication);
config.get("authenticator").as(String.class).ifPresent(this::authenticator);
config.get("authentication-optional").as(Boolean.class).ifPresent(this::authenticationOptional);
config.get("audit").as(Boolean.class).ifPresent(this::audited);
config.get("audit-event-type").as(String.class).ifPresent(this::auditEventType);
config.get("audit-message-format").as(String.class).ifPresent(this::auditMessageFormat);
config.get("audit-ok-severity").as(String.class).ifPresent(this::auditOkSeverity);
config.get("audit-error-severity").as(String.class).ifPresent(this::auditErrorSeverity);
}

public void add(Authenticated atn) {
void add(Authenticated atn) {
if (null == atn) {
return;
}
Expand All @@ -106,7 +121,7 @@ public void add(Authenticated atn) {
this.authenticator = "".equals(atn.provider()) ? null : atn.provider();
}

public void add(Authorized atz) {
void add(Authorized atz) {
if (null == atz) {
return;
}
Expand All @@ -130,7 +145,7 @@ void requiresAuthentication(boolean atn) {
this.requiresAuthentication = atn;
}

void setRequiresAuthorization(boolean atz) {
void requiresAuthorization(boolean atz) {
this.requiresAuthorization = atz;
}

Expand All @@ -154,10 +169,18 @@ boolean authenticationOptional() {
return authnOptional;
}

void authenticationOptional(boolean authnOptional) {
this.authnOptional = authnOptional;
}

boolean failOnFailureIfOptional() {
return failOnFailureIfOptional;
}

void failOnFailureIfOptional(boolean failOnFailureIfOptional) {
this.failOnFailureIfOptional = failOnFailureIfOptional;
}

boolean requiresAuthorization() {
if (null != requiresAuthorization) {
return requiresAuthorization;
Expand All @@ -171,47 +194,88 @@ boolean requiresAuthorization() {
return (count != 0) || authorizeByDefault;
}

public boolean isAtzExplicit() {
boolean atzExplicit() {
return atzExplicit;
}

String getAuthenticator() {
void atzExplicit(boolean atzExplicit) {
this.atzExplicit = atzExplicit;
}

String authenticator() {
return authenticator;
}

String getAuthorizer() {
void authenticator(String authenticator) {
this.authenticator = authenticator;
}

String authorizer() {
return authorizer;
}

public List<SecurityLevel> getSecurityLevels() {
void authorizer(String authorizer) {
this.authorizer = authorizer;
}

List<SecurityLevel> securityLevels() {
return securityLevels;
}

public boolean isAudited() {
boolean audited() {
return audited;
}

public String getAuditEventType() {
void audited(boolean audited) {
this.audited = audited;
}

String auditEventType() {
return auditEventType;
}

public String getAuditMessageFormat() {
void auditEventType(String auditEventType) {
this.auditEventType = auditEventType;
}

String auditMessageFormat() {
return auditMessageFormat;
}

public AuditEvent.AuditSeverity getAuditOkSeverity() {
void auditMessageFormat(String auditMessageFormat) {
this.auditMessageFormat = auditMessageFormat;
}

AuditEvent.AuditSeverity auditOkSeverity() {
return auditOkSeverity;
}

public AuditEvent.AuditSeverity getAuditErrorSeverity() {
void auditOkSeverity(AuditEvent.AuditSeverity auditOkSeverity) {
this.auditOkSeverity = auditOkSeverity;
}

private void auditOkSeverity(String severity) {
auditOkSeverity(AuditEvent.AuditSeverity.valueOf(severity));
}

AuditEvent.AuditSeverity auditErrorSeverity() {
return auditErrorSeverity;
}

public AnnotationAnalyzer.AnalyzerResponse analyzerResponse(AnnotationAnalyzer analyzer) {

void auditErrorSeverity(AuditEvent.AuditSeverity auditOkSeverity) {
this.auditErrorSeverity = auditOkSeverity;
}

private void auditErrorSeverity(String severity) {
auditErrorSeverity(AuditEvent.AuditSeverity.valueOf(severity));
}

AnnotationAnalyzer.AnalyzerResponse analyzerResponse(AnnotationAnalyzer analyzer) {
return analyzerResponses.get(analyzer);
}

public void analyzerResponse(AnnotationAnalyzer analyzer, AnnotationAnalyzer.AnalyzerResponse analyzerResponse) {
void analyzerResponse(AnnotationAnalyzer analyzer, AnnotationAnalyzer.AnalyzerResponse analyzerResponse) {
analyzerResponses.put(analyzer, analyzerResponse);

switch (analyzerResponse.authenticationResponse()) {
Expand Down
Loading

0 comments on commit 8211076

Please sign in to comment.