micronaut-projects / micronaut-security

The official Micronaut security solution
Apache License 2.0
169 stars 124 forks source link

ERROR WITH: Support Client Credentials Grant #642

Open IgorEulalio opened 3 years ago

IgorEulalio commented 3 years ago

I can't share the code because company policies, but i will try to explain at the maximum. Linked with this issue: https://github.com/micronaut-projects/micronaut-security/issues/12 Oriented by @sdelamo i create a new issue to relate my problem.

Explain: I have a lot of microservices, this microservices don't handle with the generate token process directly, have a thirdy party authorization in my company, that offers this urls: DNS_OF_MY_COMPANY/api/oauth/token DNS_OF_MY_COMPANY/api/oauth/token_info

When i receive a request, i receive a bearer token, and need to introspect that into token_info URL to validate.

When i need to call other microservices, depending on what microservices im calling, i need to generate a token into token url.

To do this, i have this code:

@Controller("/contratacaorecomendacaoservice")
public class ContratacaoRecomendacaoController {

    private final ValidaCadastroCvmBiz biz;

    public ContratacaoRecomendacaoController(ValidaCadastroCvmBiz biz) {
        this.biz = biz;
    }

    @Secured(SecurityRule.IS_ANONYMOUS)
    @Post(produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON, uri = "/valida_cvm")
    public HttpResponse validaCadastroCvm(@Body ValidaCadastroCvmDTORequest dto) {

        final String linksParaProximaNavegacao = biz.validaCadastroCvm(dto.getIdInvestidor());
        ValidaCadastroCvmDTOResponse situacaoCadastral = ValidaCadastroCvmDTOResponse.builder()
                .link(new LinkDTO(linksParaProximaNavegacao))
                .build();

        return HttpResponse.ok().body(situacaoCadastral);
    }
}

My http client:

@Client(id = "cvm_client")
public interface CvmClient {

    @Consumes(MediaType.APPLICATION_JSON)
    @Get("/investimentos/v1/investidores/{id_investidor}/situacoes")
    CvmServiceResponseRoot verificaSituacaoCadastral(@PathVariable("id_investidor") String idInvestidor);

}

My application.yml

 security:
    oauth2:
          clients:
            companyauthserver:
              client-id: '{my_client_id'
              client-secret: '{my_client_secret}'
              client-credentials:
                service-id-regex: 'cvm_client'
              token:
                url: "https://${dns_of_my_authorizator}/api/oauth/token"
                auth-method: client_secret_basic`

By following these documentations of micronaut security: https://micronaut-projects.github.io/micronaut-security/latest/guide/#clientcredentials

But, when i call these microservices trough my microservices, the micronaut can't handle the authorization flow, and trow this exception:

22:36:30.433 [default-nioEventLoopGroup-1-3] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: Error instantiating bean of type [io.micronaut.security.authentication.Authenticator]

Message: Bean Factory [Definition: io.micronaut.security.oauth2.endpoint.token.request.password.PasswordGrantFactory] returned null
Path Taken: new SecurityFilter(Collection securityRules,[Collection authenticationFetchers],SecurityConfiguration securityConfiguration) --> new BasicAuthAuthenticationFetcher([Authenticator authenticator],TokenConfiguration configuration) --> new Authenticator([Collection authenticationProviders],SecurityConfiguration securityConfiguration)
io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type [io.micronaut.security.authentication.Authenticator]
jameskleeh commented 3 years ago

What version of Micronaut?

IgorEulalio commented 3 years ago
2.4.2
IgorEulalio commented 3 years ago

To generate this token, my call look like this:

const echoPostRequest = {
  url: 'DNS_API/api/oauth/token',
  method: 'POST',
  header: 'Content-Type:application/x-www-form-urlencoded',
  body: {
            mode: 'urlencoded',
            urlencoded: [
                    { key: "client_id", value: "client_id" },
                    { key: "client_secret", value: "client_secret" },
                    { key: "grant_type", value: "client_credentials" },
            ]
    }
};