Keycloak Policy Enforcement Springboot - spring-boot

I am implementing Keycloak scope based permission authentication in Spring-boot application. I am using Keycloak.json file to initialize Keycloak adapter and now I applied policy in Keycloak.json file and while testing API I am getting error : failed to obtain policy enforcer
and below is my Keycloak.json file :
{
"realm": "XYZ",
"auth-server-url": "<auth-url>",
"ssl-required": "none",
"resource": "dashboard",
"verify-token-audience": true,
"credentials": {
"secret": "<client-secret>"
},
"confidential-port": 0,
"policy-enforcer": {
"user-managed-access" : {},
"enforcement-mode" : "ENFORCING",
"paths": [
{
"name" : "Resource",
"path" : "/*",
"methods" : [
{
"method": "POST",
"scopes" : ["post"]
},
{
"method": "PUT",
"scopes" : ["put"]
}
]
}
]
}
}
Exception : java.lang.RuntimeException: Failed to obtain policy enforcer at org.keycloak.adapters.KeycloakDeployment.getPolicyEnforcer(KeycloakDeployment.java:539)
~[keycloak-adapter-core-11.0.3.jar:11.0.3] at org.keycloak.adapters.AuthenticatedActionsHandler.isAuthorized(AuthenticatedActionsHandler.java:150)
~[keycloak-adapter-core-11.0.3.jar:11.0.3]at org.keycloak.adapters.AuthenticatedActionsHandler.handledRequest(AuthenticatedActionsHandler.java:60)
~[keycloak-adapter-core-11.0.3.jar:11.0.3] org.keycloak.adapters.KeycloakDeployment.getPolicyEnforcer(KeycloakDeployment.java:537)
~[keycloak-adapter-core-11.0.3.jar:11.0.3] Caused by: org.keycloak.jose.jws.JWSInputException:
java.lang.NullPointerException: Cannot invoke "String.split(String)" because "wire" is null at org.keycloak.jose.jws.JWSInput.(JWSInput.java:58)
org.keycloak.authorization.client.util.TokenCallable.call(TokenCallable.java:64) Caused by: java.lang.NullPointerException: Cannot invoke
"String.split(String)" because "wire" is null at org.keycloak.jose.jws.JWSInput.(JWSInput.java:44) ~[keycloak-core-11.0.3.jar:11.0.3]

Related

Elastic fleet server, authenticate with service account token 401

I am following the guides here to create a token for the elastic/fleet-server service account.
I successfully created the token with the command:
bin/elasticsearch-service-tokens create elastic/fleet-server fleet-token
and try to execute the request http://localhost:9200/_security/_authenticate with the bearer authorization. I receive the following error:
{
"error": {
"root_cause": [
{
"type": "security_exception",
"reason": "failed to authenticate service account [elastic/fleet-server] with token name [fleet-token]",
"header": {
"WWW-Authenticate": [
"Basic realm=\"security\" charset=\"UTF-8\"",
"ApiKey"
]
}
}
],
"type": "security_exception",
"reason": "failed to authenticate service account [elastic/fleet-server] with token name [fleet-token]",
"header": {
"WWW-Authenticate": [
"Basic realm=\"security\" charset=\"UTF-8\"",
"ApiKey"
]
}
},
"status": 401
}
It clearly understands the token because it provides the token name in the error message. The permissions for that service account are below:
"elastic/fleet-server" : {
"role_descriptor" : {
"cluster" : [
"monitor",
"manage_own_api_key"
],
"indices" : [
{
"names" : [
"logs-*",
"metrics-*",
"traces-*",
"synthetics-*",
".logs-endpoint.diagnostic.collection-*",
".logs-endpoint.action.responses-*"
],
"privileges" : [
"write",
"create_index",
"auto_configure"
],
"allow_restricted_indices" : false
},
{
"names" : [
".fleet-*"
],
"privileges" : [
"read",
"write",
"monitor",
"create_index",
"auto_configure",
"maintenance"
],
"allow_restricted_indices" : false
}
],
"applications" : [
{
"application" : "kibana-*",
"privileges" : [
"reserved_fleet-setup"
],
"resources" : [
"*"
]
}
],
"run_as" : [ ],
"metadata" : { },
"transient_metadata" : {
"enabled" : true
}
}
}
I am running Elastic/Kibana/Elastic-Agent with Docker, version 7.17.6.
The documentation seems fairly straight forward so not sure where to go from here. Any thoughts?

How to add cognito user pool authorizer to Lambda Proxy integration in Cloud Formation Template?

I have the following cloud formation JSON template. This template is the default template provided by AWS for C#(Dotnet) Web API Lambda proxy integration.
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Transform" : "AWS::Serverless-2016-10-31",
"Description" : "An AWS Serverless Application that uses the ASP.NET Core framework running in Amazon Lambda.",
"Parameters" : {
"ShouldCreateBucket" : {
"Type" : "String",
"AllowedValues" : ["true", "false"],
"Description" : "If true then the S3 bucket that will be proxied will be created with the CloudFormation stack."
},
"BucketName" : {
"Type" : "String",
"Description" : "Name of S3 bucket that will be proxied. If left blank a new table will be created.",
"MinLength" : "0"
}
},
"Conditions" : {
"CreateS3Bucket" : {"Fn::Equals" : [{"Ref" : "ShouldCreateBucket"}, "true"]},
"BucketNameGenerated" : {"Fn::Equals" : [{"Ref" : "BucketName"}, ""]}
},
"Resources" : {
"ProxyFunction" : {
"Type" : "AWS::Serverless::Function",
"Properties": {
"Handler": "DotnetLanmada::DotnetLanmada.LambdaEntryPoint::FunctionHandlerAsync",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [ "AWSLambdaFullAccess" ],
"Environment" : {
"Variables" : {
"AppS3Bucket" : { "Fn::If" : ["CreateS3Bucket", {"Ref":"Bucket"}, { "Ref" : "BucketName" } ] }
}
},
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/{proxy+}",
"Method": "ANY"
}
}
}
}
},
"Bucket" : {
"Type" : "AWS::S3::Bucket",
"Condition" : "CreateS3Bucket",
"Properties" : {
"BucketName" : { "Fn::If" : ["BucketNameGenerated", {"Ref" : "AWS::NoValue" }, { "Ref" : "BucketName" } ] }
}
}
},
"Outputs" : {
"S3ProxyBucket" : {
"Value" : { "Fn::If" : ["CreateS3Bucket", {"Ref":"Bucket"}, { "Ref" : "BucketName" } ] }
}
}
}
This template creates a Lambda function, API Gateway, and an S3 bucket. All the requests to API gateway are proxy-ed to the Lambda function. I want to authenticate all the requests to API gateway using an existing Cognito user pool. Basically, the API gateway will have a Cognito user pool authorizer and the proxy function is authorized with that. Since the API Gateway creation part is hidden in this template I have no clue how to add a Cognito user pool authorizer here.
Thanks in advance.
One way to achieve what you want is to export the ARN of your Lambda function, and then import it into your API Gateway stack.
To export your function's ARN, in your Outputs section add:
"Function": {
"Value": ProxyFunction.Arn,
"Export": {
"Name": "ProxyFunction::Arn"
}
}
You will also need to have an invocation permission for API Gateway to invoke your function. You can add something like this to your stack:
"LambdaInvocationPermission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": { "Fn::GetAtt" : [ "ProxyFunction", "Arn" ] },
"Principal": "apigateway.amazonaws.com"
}
}
Then in your API Gateway stack, you can reference your function's ARN with
{ "Fn::ImportValue" : "ProxyFunction::Arn" }

Why WireMock says that the Request not matches? Spring cloud contract

Wiremock logs that the following request not matches:
WireMock : Request was not matched:
{
"url" : "/api/accounts?username=defaultuser",
"absoluteUrl" : "http://localhost:11651/api/accounts?username=defaultuser",
"method" : "GET",
"clientIp" : "127.0.0.1",
"headers" : {
"authorization" : "bearer test123",
"accept" : "application/json, application/*+json",
"user-agent" : "Java/1.8.0_121",
"host" : "localhost:11651",
"connection" : "keep-alive"
},
"cookies" : { },
"browserProxyRequest" : false,
"loggedDate" : 1500711718016,
"bodyAsBase64" : "",
"body" : "",
"loggedDateString" : "2017-07-22T08:21:58Z"
}
Closest match:
{
"urlPath" : "/api/accounts",
"method" : "GET",
"headers" : {
"authorization" : {
"matches" : "^bearer"
},
"accept" : {
"equalTo" : "application/json, application/*+json"
},
"user-agent" : {
"equalTo" : "Java/1.8.0_121"
},
"host" : {
"matches" : "^localhost:[0-9]{5}"
},
"connection" : {
"equalTo" : "keep-alive"
}
},
"queryParameters" : {
"username" : {
"matches" : "^[a-zA-Z0-9]*$"
}
}
}
Is the problem because of the difference of url and urlPath?
I also tried to specify absoluteUrl in the Contract. but it is ignored. I guess because it is not defined in Contract DSL.
The request side of the contract looks like this:
request{
method 'GET'
url('/api/accounts'){
queryParameters {
parameter('username', $(consumer(regex('^[a-zA-Z0-9]*$')), producer('defaultuser')))
}
}
headers {
header('authorization', $(consumer(regex('^bearer')), producer(execute('authClientBearer()'))))
header('accept', $(consumer('application/json, application/*+json')))
header('user-agent', $(consumer('Java/1.8.0_121')))
header('host', $(consumer(regex('^localhost:[0-9]{5}'))))
header('connection', $(consumer('keep-alive')))
}
}
It turned out to be a missing / at the end of the URL in the contract/stub
Not directly related to the question but for all who came here from Google:
In my case I was in the wrong scenario state.
More about scenario states here: http://wiremock.org/docs/stateful-behaviour/
If you have the same problem, maybe it's about your problem:
JSON configuration for matching mvcMock example:
"request": {
"urlPath": "/hello?name=pavel",
"method": "GET",
..
}
And you can see in log:
"/hello?name=pavel" | "/hello?name=pavel" - URL does not match
This is correct.
You have to change:
"request": {
"urlPath": "/hello",
"method": "GET",
"queryParameters": {
"name": {
"equalTo": "pavel"
}
},
..
}

AWS Cloud formation - how to get public ip address for ec2 instance

I am trying to create ec2 instance, and I want to be able to create a file that will contain ec2 instance public DNS name although in the following code I am getting circular dependency error caused by line:
"server_name = \"",{ "Fn::GetAtt" : [ "ECServer", "PublicDnsName" ]},"\"\n","\n"
Is it possible to get the public DNS name in the instance section when I am trying to create ec2?
"ECServer": {
"Type": "AWS::EC2::Instance",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"configSets": {
"Install": ["ECServerConfig"]
},
"ECConfig": {
"files": {
"/tmp/test.txt" : {
"content": { "Fn::Join" : ["", [
"server_name = \"",{ "Fn::GetAtt" : [ "ECServer", "PublicDnsName" ]},"\"\n","\n"
]]},
"mode" : "000644",
"owner": "root",
"group": "root"
}
}
}
}
},
You can get public IP of the running EC2 instance by using simple curl command as-
1. SSH to that EC2 instance.
2. Execute following command-
curl http://169.254.169.254/latest/meta-data/public-ipv4
You can try using this, in CFT one cannot use the refer to the properties of itself using Fn::GetAtt function
"ECServer": {
"Type": "AWS::EC2::Instance",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"configSets": {
"Install": ["ECServerConfig"]
},
"ECConfig": {
"files": {
"/tmp/test.txt" : {
"mode" : "000644",
"owner": "root",
"group": "root"
}
},
"commands" :{
"test" : {
"command" : "curl -s http://169.254.169.254/latest/meta-data/public-hostname > /tmp/test.txt",
"ignoreErrors" : "false"
}
}
}
}
}
}

LBCookieStickinessPolicy - cloudformation

I am not able to set LBCookieStickinessPolicy for ELB using the cloudformation script.
"LBCookieStickinessPolicy": [
{
"PolicyName": "Sample",
"CookieExpirationPeriod": "180"
}
]
You need to associate this policy with a listener. Include the policy name in the listener's PolicyNames property.
"LBCookieStickinessPolicy" : [{
"PolicyName" : "Sample",
"CookieExpirationPeriod" : "180"
} ],
"Listeners" : [ {
"LoadBalancerPort" : "80",
"InstancePort" : { "Ref" : "InstancePort" },
"Protocol" : "HTTP",
"PolicyNames" : [ "Sample" ]
} ],

Resources