I'm having issues disabling the CSRF protection in an automated fashion. I want to disable with a groovy init script or just in a property file before Jenkins Master Starts. I'm not sure why I'm getting a crumb issue I assume it has to do with the exposed LB in K8S / AWS. I'm using AWS ELB to expose pods and its causing a csrf exception in the crumb, and I also get a reverse proxy warning sometimes when I goto manage Jenkins.
I researched the issue it said I could enable the expanded proxy compatibility or disable the CSRF checking. I haven't found the groovy or config files where these live.
My current groovy init script is as follows:
import hudson.security.csrf.DefaultCrumbIssuer
import jenkins.model.Jenkins
def j = Jenkins.instance;
j.setCrumbIssuer(null); // I've also tried setting a new crumb issuer here as well.
j.save();
System.setProperty("hudson.security.csrf.CrumbFilter", "false");
System.setProperty("hudson.security.csrf", "false");
System.setProperty("hudson.security.csrf.GlobalCrumbIssuerConfiguration", "false");
I can't seem to find the reference as to how to disable this property or enable the Enable proxy compatibility property either.
Crumb Algorithm
Default Crumb Issuer
Enable proxy compatibility
I intercepted the request to configure when I click apply and the json payload passed seems like the setting is
"hudson-security-csrf-GlobalCrumbIssuerConfiguration": {
"csrf": {
"issuer": {
"value": "0",
"stapler-class": "hudson.security.csrf.DefaultCrumbIssuer",
"$class": "hudson.security.csrf.DefaultCrumbIssuer",
"excludeClientIPFromCrumb": true
}
}
},
im not sure what or how I'm supposed to set these.
If you really need to (temporarily) disable CSRF it can be done with groovy:
import jenkins.model.Jenkins
def instance = Jenkins.instance
instance.setCrumbIssuer(null)
It should be enabled afterwards again by setting to the Default CrumbIssuer again
as mentioned in the Jenkins Wiki:
import hudson.security.csrf.DefaultCrumbIssuer
import jenkins.model.Jenkins
def instance = Jenkins.instance
instance.setCrumbIssuer(new DefaultCrumbIssuer(true))
instance.save()
N.B.: It's not enough to set the Flag to enable CSRF protection via the GUI afterwards, you need to check the crumb algorithm, too.
I stumbled on this question while I was tearing my hair out trying to figure out more or less the same thing (in my case, I needed to know how the proxy compatibility option mapped to Jenkins' config.xml). In the HTML source for the form, there's this helpful bit of info (truncated for brevity):
<label>Enable proxy compatibility</label><a helpURL="/descriptor/hudson.security.csrf.DefaultCrumbIssuer/help/excludeClientIPFromCrumb"><img /></a>
excludeClientIPFromCrumb is a constructor parameter on DefaultCrumbIssuer, as the javadocs expose: http://javadoc.jenkins-ci.org/hudson/security/csrf/DefaultCrumbIssuer.html. I just needed to flip that value in my config.xml - my confusion stemmed from how the label for the field in the UI differed from the name of the constructor argument.
For your case, if you want to enable CSRF protection using the default crumb provider with "enable proxy compatibility" turned on, in your script you can do
j.setCrumbIssuer(new DefaultCrumbIssuer(true));
Instead of disabling the CSRF, you can simply add a crumb in your request so that you won't get that error anymore. Please go through this link to do it. Please go through this link for more info. Hope this helps.
Related
My application requires the app to run in https since the browser sends payment data to payment gateway through javascript library.
If the app is run in http then this error is thrown by the payment gateway.
I have created a simple hello world app and wrote a simple geb spec.
I dont seem to find a way to run the server in https mode. I dont find any helpful resource in the web as well.
Right now it is running in http mode in random port
Grails application running at http://localhost:54461 in environment: test
I have tried adding https port in build.gradle as
integrationTest {
systemProperty "webdriver.chrome.driver", "C:\\webdrivers\\chromedriver.exe"
jvmArgs(
'-Dgrails.server.port.https=8443'
)
}
But that seems to get ignored.
I have also tried setting the https port in intellij run configuration as shown below.
I have published the app code in github for reference.
https://github.com/learningcscience/gebhttps
I appreciate any help. Thanks!
UPDATE:
Today i think i made a little more progress.
I could now run the app in a fixed port. I ran the app in 8443 which is for https.
I did this using the spring boot test annotation
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
In the console now it shows
Grails application running at http://localhost:8443 in environment: test
Starting ChromeDriver 100.0.4896.20 (f9d71f93d32a6487809d6f35a9670c879fe97dfe-refs/branch-heads/4896#{#203}) on port 31898
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
https://docs.grails.org/latest/guide/testing.html
Now i just need to make the app run using the https rather than http.
I have updated the code in github repo.
https://github.com/learningcscience/gebhttps
I appreciate any help! Thanks!
ok. The problem is finally solved.
The last help came from the grails community at https://grails.slack.com/
Thanks Mattias Reichel for the help.
I am now going to put step by step process so that others might not get stuck with this issue.
In order to run functional geb test in https you first need to put SpringBootTest annotation as mentioned in above UPDATE: section.
I am pasting here again
#Integration
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class EventCreationSpec extends GebSpec {
After that you set baseurl in src/integration-test/resources/GebConfig.groovy.
I put baseUrl = "https://localhost:8443/"
My GebConfig looks like this
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
import org.openqa.selenium.firefox.FirefoxDriver
environments {
// run via “./gradlew -Dgeb.env=chrome iT”
chrome {
driver = {
System.setProperty('webdriver.chrome.driver', 'C:\\webdrivers\\chromedriver.exe')
new ChromeDriver()
}
}
// run via “./gradlew -Dgeb.env=chromeHeadless iT”
chromeHeadless {
driver = {
ChromeOptions o = new ChromeOptions()
o.addArguments('headless')
new ChromeDriver(o)
}
}
// run via “./gradlew -Dgeb.env=firefox iT”
firefox {
driver = { new FirefoxDriver() }
}
}
baseUrl = "https://localhost:8443/"
After that you need to create a application-test.yml file in src/integration-test/resources/
The application-test.yml file looks like this
server:
port: 8443
ssl:
enabled: true
keyStore: c:/Users/user/selfsigned.jks
keyStorePassword: pepsicola
keyAlias: tomcat
you need to create self signed certificate.
You can go through this process to create the certificate
https://grails.org/blog/2017-06-28.html
In the configuration above
my certificate was in selfsigned.jks keystore in the path c:/Users/user/selfsigned.jks
After that the functional test will fire in https mode
In my case
http://localhost:8443/roadrace
here is what the gebspec should look like
Note the SpringBootTest annotation at the top.
#Integration
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
#Stepwise
class EventCreationSpec extends GebSpec {
def grailsApplication
def springSecurityService
def timeService
def setup() {
}
def cleanup() {
}
void "Create and publish event"() {
when:"The home page is visited"
go '/roadrace/'
$("#details-button").click()
$("#proceed-link").click()
... rest of gebspock test steps....
then:"The title is correct"
title == "Homepage"
}
}
Please note that i had to go to /roadrace/ because the roadrace is the app context path.
If you dont have context path you can go to go '/'
The final hurdle can be when the browser fires up in https it might show
For this using geb you can click on the Advanced and then Proceed to localhost (unsafe) links
I just click the links like this
go '/roadrace/'
$("#details-button").click()
$("#proceed-link").click()
That's all! Now the geb functional test runs in https. Since it is https you can also now communicate to test payment gateway.
Question
I have the following script as part of a declarative pipeline in Jenkins
stages {
stage('sql') {
steps {
step([
$class: 'SQLPlusRunnerBuilder',
credentialsId:"sis-database-prod-schema-test",
instance:"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db_${ENVIRONMENT}.int.excelsior.edu)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=${ENVIRONMENT})))",
scriptType:'userDefined',
script: '',
scriptContent:"select*from dual",
customOracleHome: '/usr/lib/oracle/12.2/client64'
])
}
}
}
You will notice I am referencing the credential ID sis-database-prod-schema-test. When I scope this credential globally this script works. However, when I scope the credential at the folder level it get the following error
ERROR: Invalid credentials [sis-database-prod-schema-test]. Failed to initialize credentials or load user and password
Here is a screenshot of my folder-level scope configuration
Additional Information
When I scope the credential at the folder level I can see it in a configuration drop down element ONLY when I am in the appropriate folder. So, in my mind, the scope configuration is correct but there referencing ( in the code ) is wrong.
The entry I have highlighted is the sis-database-prod-schema-test credential ID. The one below it ( sis-test-database-prod-schema ) is a global credential unrelated to this question
Edit : This Was a Known Issue
This is a known bug that the author was unable to fix. The relevant code is here. You can issue a pull request to fix the bug.
I don't know if you still care but I just submitted a pull request for this that got accepted. Now this problem should be fixed.
Known Issue
This is a known bug that the author was unable to fix. The relevant code is here. You can issue a pull request to fix the bug.
I am using Azure API Management to host three versions of an API - dev, qa, stage. These are basically three different build configurations of the api, so when imported to APIM - "MyAPI-dev", "MyAPI-qa", "MyAPI-stage".
I am using swagger for documentation. When I trigger a revision in Terraform to build/re-create the API definitions, i am getting error:
"my-ApiM-dev" / Resource Group "rg-myApim"): apimanagement.APIClient#CreateOrUpdate: Failure sending
request: StatusCode=409 -- Original Error: Code="IdentifierAlreadyInUse" Message="Resource already exists."
I am 99% sure this is due to the "title" in SwaggerConfig.cs file, it is the same value for all configurations. Thus deploying two of the APIs with the same title is throwing the error.
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "MyApiTitle");
}
How can I get the title to be unique based on the configuration?
I tried creating config values in web.config value for each configuration and referencing the key in the config file, but it didn't work, SwaggerUi picked up the default value in web.config file only.
web.dev.config:
<add key="BuildConfig" value="dev" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
SwaggerConfig.cs:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "MyApiTitle-" + ConfigurationManager.AppSettings["BuildConfig"]);
}
Another option is to script deleting the API, import the API and rename the title, but I would do that as a last resort.
Would like to do this dynamically in the project code though.
I am able to achieve this with PowerShell, please check if that helps to you
https://medium.com/#rakesh.suryawanshi/deploy-azure-web-api-into-azure-api-management-with-powershell-3d14d1610b07
also, check if you are able to deploy it manually with your approach.
I create a Cloud Run client, however, couldn't find a way to list a service that is deployed with Cloud Run on GKE (for Anthos).
Create the client:
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleCredentials credential = GoogleCredentials.getApplicationDefault();
credential.createScoped("https://www.googleapis.com/auth/cloud-platform");
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credential);
CloudRun.Builder builder = new CloudRun.Builder(httpTransport, jsonFactory, requestInitializer);
return builder.setApplicationName(applicationName)
.setRootUrl(cloudRunRootUrl)
.build();
} catch (IOException e) {
e.printStackTrace();
}
try to list services:
services = cloudRun.namespaces().services()
.list("namespaces/default")
.execute()
.getItems();
My "hello" service is deploy on a GKE cluster under the namespace default. The above code doesn't work because the client always see "default" as project_id and complains about permission stuff. If I put the project_id rather than "default", permission errors are gone, but no services will be found.
I tried another project that does have Google fully-managed cloud run services, the same code returns result (with .list("namespaces/")).
How to access the service on GKE?
And my next question would be, how to programmatically create Cloud Run services on GKE?
Edit - for creating a service
As I couldn't figure out how to interact with Cloud Run on GKE, I took a step back to try fully managed one. The following code to create a service fails, and the error message just doesn't provide much useful insight, how to make it work?
Service deployedService = null;
// Map<String,String> annotations = new HashMap<>();
// annotations.put("client.knative.dev/user-image","gcr.io/cloudrun/hello");
ServiceSpec spec = new ServiceSpec();
List<Container> containers = new ArrayList<>();
containers.add(new Container().setImage("gcr.io/cloudrun/hello"));
spec.setTemplate(new RevisionTemplate().setMetadata(new ObjectMeta().setName("hello-fully-managed-v0.1.0"))
.setSpec(new RevisionSpec().setContainerConcurrency(20)
.setContainers(containers)
.setTimeoutSeconds(100)
)
);
helloService.setApiVersion("serving.knative.dev/v1")
.setMetadata(new ObjectMeta().setName("hello-fully-managed")
.setNamespace("data-infrastructure-test-env")
// .setAnnotations(annotations)
)
.setSpec(spec)
.setKind("Service");
try {
deployedService = cloudRun.namespaces().services()
.create("namespaces/data-infrastructure-test-env",helloService)
.execute();
} catch (IOException e) {
e.printStackTrace();
response.add(e.toString());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
}
Error message I got:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "The request has errors",
"reason" : "badRequest"
} ],
"message" : "The request has errors",
"status" : "INVALID_ARGUMENT"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:150)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
And the base_url is: https://europe-west1-run.googleapis.com
Your question is quite detailed (and is about Java which I am no expert in) and there are actually too many questions in there (ideally, please ask only 1 question here). However, I'll try to answer a few things you asked:
First, Cloud Run (managed, and on GKE) both implement the Knative Serving API. I've explained this at https://ahmet.im/blog/cloud-run-is-a-knative/ In fact, Cloud Run on GKE is just the open source Knative components installed to your cluster.
And my next question would be, how to programmatically create Cloud Run services on GKE?
You will have a very hard time (if possible at all) using the Cloud Run API client libraries (e.g. new CloudRun above) because these are designed for *.googleapis.com endpoints.
The Knative API part of "Cloud Run on GKE" is actually just your Kubernetes (GKE) master API endpoint (which runs on an IP address, with a TLS certificate that isn't trusted by root CAs, but you can find the CA cert in GKE GetCluster API call to verify the cert.) The TLS is part is why it's so hard to use the API Client libraries.
Knative APIs are just Kubernetes objects. So your best bet is one of these:
See Kubernetes java client (https://github.com/kubernetes-client/java) actually allows dynamic objects. (Go implementation does) and try to use that to create Knative CRDs.
Use kubectl apply.
Ask Knative Serving open source repository for help (they should be providing client libraries, maybe they're already there I'm not sure)
To program Cloud Run (managed) with the API Client Libraries, you need to explicitly override the API endpoint to the region e.g. us-central1-run.googleapis.com. (This is documented on each API call's REST API reference documentation.)
I have written a blog post in detail (with sample code in Go) on how to create/update services on Cloud Run (managed) using the Knative Serving API here: https://ahmet.im/blog/gcloud-run-deploy/
If you want to see how gcloud run deploy works, and which APIs it calls, you can pass --log-http option to observe the request/response traffic.
As for the error you got, it seems like the error message isn't helpful, but it might be coming from anywhere (as you're trying to imitate Knative API in GCP client libraries). I recommend reading my blog posts and sample code in depth.
UPDATES: Our engineering team's looking at the issue, it appears that there's currently a bug not adding the "details" field to the error. That's being worked on.
In your case, we see the following errors from requests:
field: "spec.template.spec"
description: "Missing template spec."
Means you are not properly filling up the spec field as I shown in my blog post and sample code.
field: "metadata.name"
description: "The revision name must be prefixed by the name of the enclosing Service or Configuration with a trailing -"
Make sure the name you are specifying adheres the patterns specified in API docs. Try to create that name manually perhaps in the UI or gcloud CLI.
field: "api_version"
description: "Unsupported API version \'serving.knative.dev/v1\'. Expected \'serving.knative.dev/v1alpha1\'"
Do not use v1alpha1 API, use v1 directly.
We'll try to get the details to the error message, however it appears that you need to study the sample code I linked in my blog post more in detail:
https://github.com/GoogleCloudPlatform/cloud-run-button/blob/a52c7fbaae33a3e06c112206c7227a0ef9649647/cmd/cloudshell_open/deploy.go#L26-L112
The Java SDK is automatically generated from the fact that the Cloud Run (fully managed) API is public. It does not support Cloud Run for Anthos.
(gcloud.run.deploy) The revision name must be prefixed by the name of the enclosing Service or Configuration with a trailing -revision name
revision name name should be 65 character then problem will be resolved in Automation pipeline with GCP revision suffix should be less revision name is the combination of (service name +revision suffix) will automatically created by GCP.
I installed ERP "Openbravo" following the custom approach:
So I followed the steps from the tutorial.I set "localhost" for the parameter "Web URL" in the configuration file. After that I ran the servers, Apache and Tomcat.
When accessing the application via browser using http://localhost/openbravo
The problem I am facing is that,the browser doesn't find some components.
I got this log in console of Google-chrome like this:
Login_F1.html:11 GET http://localhost/openbravo/security/localhost/js/ajax.js 404 (Not Found)
When i try to accede to the previous url in a new tab i got "not found",
but when i change by this URL "http://localhost/openbravo/web/js/utils.js" works well.
My question is that how i can make Openbravo generate "/web/" instead "/security/localhost/".
If you look at Openbravo.properties file
.....
//Static content URL. Use the default value to make it dynamic.
//Don't change this unless you know what you are doing
web.url=#actual_url_context#/web
// Full URL of the context, *only* used by the Web Services installation
and diagnostic task
context.url=http://localhost:8080/openbravo
.....
#actual_url_context# will get replaced by domain name with port number and application context name (for example: mydomain:8989/openbravo)
404 is due to application is not able to locate ajax.js under
../web/ajax.js
1 ==> To fix the issue you can just restore to #actual_url_context# and perform smartbuild.
or do an install.source
2 ==> To add any client side customization or to support static content under web folder you can follow
an example: http://wiki.openbravo.com/wiki/How_to_add_a_button_to_the_toolbar
http://wiki.openbravo.com/wiki/How_to_create_a_Manual_UI_Process