helidon-io / helidon

Java libraries for writing microservices
https://helidon.io
Apache License 2.0
3.53k stars 565 forks source link

Not able to use env variable on ScopeValidator.Scope annotation #2987

Open bcoreddy opened 3 years ago

bcoreddy commented 3 years ago

Hi Team, I'm not able to expose scope value as an environment variable, because when we switch environments, the scope value may differ. For example, I'm reading the variable like below.

Config config = Config.builder().build();
private final String scope = config.get("APPLICATION_SCOPE").asString().get();

Now when I try to use scope on ScopeValidator.Scope annotation, it is not allowing me to use and compiler error says "Attribute value must be constant" @ScopeValidator.Scope(scope)

spericas commented 3 years ago

Annotation members must be constants in Java. If that is not the case in your environment, you will need to create a ScopeValidator and call its validate() method manually to check scopes passing the value read from Config. If you have already found a solution, please close the issue.

bcoreddy commented 3 years ago

No, I did not found a solution for this. In fact, I have discussed about this issue with "Tomas Langer" on slack channel #helidon-users where he suggested to create custom annotation to validate scopes in my service and use Config to get environment variable to pass the scope value to the annotation/method. And he has suggested me to submit an issue to enhance out of box ScopeValidator as well.

spericas commented 3 years ago

@bcoreddy OK. You can always re-title this issue for that if you like.

tomas-langer commented 3 years ago

Using configuration to set up mapping of scopes is feasible for abac authorization. It is not that simple when OidcProvider is also in use, as it analyzes the @Scope annotations itself as well (to correctly request scopes on initial request without a token). I could implement this in a "dirty" way - duplicate the mapping configuration - both for abac/scope-validator and for oidc, which I do not like. I am trying to find a way to implement this that could be reused by both places. Example of the configuration:

security:
  providers:
    - abac:
        scope-validator:
          scope-map:
            "first_scope": "mapped_first_scope"
            "second_scope": "mapped_second_scope"

This would allow using any string in the annotation that could be mapped to any other name (limited by what is allowed in keys of the used configuration source). Another option would be to use a config reference in the annotation itself (e.g. @Scope("${scopes.first-scope-key}|first_scope"}) with default value (the syntax is not final). This approach has a drawback - we do not have access to root of configuration in any of the security components, so this would be quite a major refactoring...