How to add http method into Resource of Keycloak - keycloak

I want keycloak protect my Restful URL, eg: POST /user/1, DELETE /user/1.
When I create a new resource in Keycloak, I found there are ONLY uris , but no HTTP method exists.
So how can I distinguish between DELETE and POST.

Keycloak Gatekeeper has concept of resources, where you can define also authorization on the request method level, e.g.:
resources:
- uri: /*
- uri: /users/*
methods:
- GET
roles:
- viewer
- uri: /users/*
methods:
- POST
- DELETE
roles:
- editor

There is a possible solution using Authorization Scopes. You can create GET, POST, DELETE authorization scopes and associate them with your resource and then create scope base permission. For example when integrating with Spring Boot you just provide this setting in application.properties:
keycloak.policy-enforcer-config.http-method-as-scope=true

Related

Is it possible to validate Auth0 JWTs with Kong without assigning to users

I have an authentication flow with auth0 that exists outside of a declaratively configured Kong Gateway setup but still want to validate tokens at the edge. It's expected that calling users will always pass an authorization header with a bearer token that they've received from a login endpoint that calls an internal auth service.
After reading the Kong docs it seems like you need to assign the pubkey/JWK to a consumer which I don't quite understand. I don't want to manage users through Kong. I have seen mention of consumer being able to be an "anonymous" user which may be a blanket way to apply this, but I'm unsure of how to configure this declaratively.
Is this possible without writing custom middleware?
I believe you can use the Kong JWT Signer plugin to validate your bearer token with the JWK server, even without a consumer, by leaving access_token_consumer blank in the configuration and using other claims to verify the JWT token.
By following this instruction, you should be able to understand the inner working of the plugin and figure it out from there.
The cleanest way to do this is with Plus/Enterprise Kong and using their OpenID Connect plugin. I want to keep this limited to their open source Kong deployed in a single container with declarative configuration, however. I've managed to figure out how to accomplish this as such.
You can create a consumer with any username and the jwt_secrets field are applied to the plugin somehow. I have no idea how or why. Here is an example kong.yaml:
_format_version: "2.1"
services:
- name: mock-grpc-service-foo
host: host.docker.internal
port: 4770
protocol: grpc
routes:
- name: foo-routes
protocols:
- http
paths:
- /hello
plugins:
- name: grpc-gateway
config:
proto: proto/foo.proto
consumers:
- username: anonymous # this can be anything
jwt_secrets:
- algorithm: RS256
key: https://company_name_here.auth0.com/
rsa_public_key: |
-----BEGIN PUBLIC KEY-----
... pub key here ...
-----END PUBLIC KEY-----
secret: this-does-not-seem-to-matter
plugins:
- name: jwt
service: mock-grpc-service-foo
You can derive your public key from your Auth0 JWK like so:
curl https://COMPANYNAME.auth0.com/pem > COMPANYNAME.pem
then
openssl x509 -pubkey -noout -in COMPANYNAME.pem > pubkey.pem
I'm doing this with REST->gRPC mappings, but you can do the same with regular regular routing. You can apply this plugin globally, to services or routes.
Declaratively configuring this opens up a whole new can of worms as you need to do templating with an entry script in order to inject the correct pub key for each environment this is deployed in provided you have different Auth0 tenants, but this gets you a lot of the way there.

How to add lambda invoke role in custom authorizer of api gateway using serverless framework

I would like to add Lambda invoke role in custom authorizer for an api gateway using serverless framework.
events:
- http:
path: controls
method: GET
cors: ${self:custom.lambdaCORS}
authorizer:
arn: arn:aws:lambda:us-east-1:XYZ:function:SLS-XYZ
managedExternally: true
identitySource: method.request.header.x-api-key
resultTtlInSeconds: 0
type: request
Can someone help me in finding the property under authorizer to add "Lambda invoke role". I was able to do it manually from aws console. I am trying to access authorizer defined in other region. It seems API gateway needs a permission to invoke lambda authorizer in another region.
So the solution I was able to come up with was to add a specific permission to the generate API Gateway Cloudformation template.
The AWS docs outline what the Cloudformation template should look like to add a permission for API Gateway to access a lambda:
https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-rest-api-lambda-integrations/#To_add_Lambda_invoke_permission_to_a_REST_API_with_a_Lambda_integration_using_a_CloudFormation_template
So if you adapt that and add this block to the bottom of your serverless.yaml you should be able to access the Authorizer referenced by the FunctionName field!
resources:
Resources:
InvokeAuthorizerPermission:
Type: AWS::Lambda::Permission
Properties:
Action: "lambda:InvokeFunction"
FunctionName: ARN_OF_AUTHORIZER
Principal: "apigateway.amazonaws.com"
SourceArn: "arn:aws:execute-api:${aws:region}:${aws:accountId}:*/*/*/*"
Hope this helps another lost soul and I smashed my head up against this for a good long while!

Multiple authentications (Basic Auth + Keycloak)

I have 2 different rest endpoints in my Quarkus project:
/api/ws/...
/api/web/...
according to my understanding, it is so with Keycloak that I get a bearer token before and with this token I can access the endpoints.
But how do I do that if I want to secure the "ws" endpoint only with basic auth (Username + Password)?
So that I have then also the user in the SecurityIdentity (Principal) contained ?
the current "application.properties" looks like this:
# AUTH
quarkus.http.auth.basic=true
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated
quarkus.http.auth.permission.web.paths=/*
quarkus.http.auth.permission.web.policy=authenticated
quarkus.oidc.tenant-id=RealmResolver
quarkus.oidc.enabled=true
quarkus.oidc.auth-server-url=${keycloak.url}/auth/realms/${keycloak.realm}
quarkus.oidc.client-id=${keycloak.client_id}
quarkus.oidc.token-path=${keycloak.url}/auth/realms/${keycloak.realm}/protocol/openid-connect/token
quarkus.oidc.token.refresh-expired=true
quarkus.oidc.application-type=WEB_APP
## WS
quarkus.http.auth.ws.basic=true
quarkus.oidc.ws.auth-server-url=${keycloak.url}/auth/realms/${keycloak.realm}
quarkus.oidc.ws.client-id=${keycloak.client_id}
quarkus.oidc.ws.application-type=hybrid
quarkus.http.auth.permission.ws.paths=/api/ws/*
quarkus.http.auth.permission.ws.policy=authenticated
Quarkus can support several authentication mechanisms at the same time - but at the moment it can not apply only one mechanism for a specific request path. Please watch https://github.com/quarkusio/quarkus/issues/11886
thanks

Swagger Open API security Schema giving Object error

I am having trouble in setting security schema in open api swagger spec in yaml.
I get below error while setting security schemas:
in paths I did use Bearerauth but still same issue:
paths:
/v1/items:
get:
tags:
- Item Resources
summary: searches items
security:
- BearerAuth: [adsfdf]
operationId: searchItems
description: |
Any suggestion on how to fix this issue, or there is any issue with implementation ?
Your global security definition is indented. Global security is defined at the top level, not inside the auth type or component definitions.
Also, in your path usage, you've defined a scope adsfdf. Security scopes do not work with Bearer Authentication - this format is present in OpenAPI for the purpose of OAuth. For more details, see Swagger's documentation.
security:
- bearerAuth: [] # use the same name as above

What do I put in Authorization header for calls to API Gateway?

I am able to call my rest api in api gateway by passing the users IdToken in the Authorization header when using Cognito User Pools.
However now I'm trying to call api gateway using Cognito federated identities, therefore an iam user. What do I send in the Authorization header in this case?
I'm calling lambda using proxy+
If you have done the part with Cognito with user pool and federated identifies, you can use AWS_IAM as authorizer.
get:
handler: get.main
events:
- http:
path: notes/{id}
method: get
cors: true
authorizer: aws_iam