Submitting sonar-runner jobs to SonarQube with SSO via reverse proxy - sonarqube

Our organization has SSO authentication via an Apache reverse proxy, which is currently working flawlessly. I was surprised how easy it was to configure!
Now that I have this set up, however, I find that I am not able to submit jobs using sonar-runner. When I look at the logs, I see that every access is redirected to the Federated SSO login page.
Is there some additional configuration that needs to be done to allow scans to go through without being authenticated? Or perhaps some configuration options that need to be passed to the sonar-runner itself?
EDIT: We did consider a couple of options.
First, we thought about allowing only the URLs necessary to submit jobs to pass through the reverse proxy without authentication. This is a tedious process at best and allows a path of entry into the service itself without authentication.
Second, we thought about passing a user token along with the request. There are two issues with this approach. First, the existing URL is set up to authenticate using a three-legged approach. As far as I know, I can't set up both two-legged and three-legged authentication for the same URL. Second, we are submitting jobs using the Sonarqube plugin in Jenkins. Without modifying the plugin itself, there is no way to get a user token to pass through to the submit request.
Our workaround for the moment: Since both systems are running in Docker containers, we submit from Jenkins by passing it to the IP address of the Sonarqube container. This has the undesired effect of formatting the Sonarqube report links with a 172.17.0.x address rather than the FQDN.

Related

How can I make authorized requests to secured API endpoint from cronjobs?

I have a golang application which has API key authorization via the JWT token
I am using Kubernetes. So, this golang app is in a pod.
Now, I want to create another application for cronjobs to hit golang endpoint once a week.
What I need:
How to do / skip the authorization?
skip: Ingress is not required here as I can simply call it internally. Can that help this case?
What I Tried:
I tried keeping the cronjobs and api in the same application so I can simply call the service instead of the endpoint, But that also has a drawback.
I am not able to create replicas as they will also replicate the cronjobs and the same endpoint will be hit 1*no of replicas times
I want to call "abc.com" endpoint once a week. It requires a token and I cannot simply pass a token.
I hope there is some way around this.
If you just have to call them internally without exposing them, it can certainly help.
Provided both Pods (and therefore Deployments) are running under the same Cluster you can use Kubernetes' internal DNS.
K8s automatically creates DNS records for Services you create that can be used for internal communication by following this specific format: <service-name>.<service-namespace>.svc.cluster.local
More information from the official docs here: DNS for Services and Pods
If it sounds weird or if it can help understanding the gist of it, try to think of the "endpoint" as a rule you add to your system's hosts file: it boils down to basicly adding a rule where <service-name>.<service-namespace>.svc.cluster.local points to your pod's IP address, except it's done automatically
E.g.
Your golang app is running inside a Pod.
You created a Service pointing to it, named go-api and under the namespace go-apps.
If your cron-job worker is running in a Pod inside the same cluster, you can use go-api.go-apps.svc.cluster.local[:<port>] to reach your app without using an Ingress
The authorization is up to you, since you're usually handling it either directly or by using specific frameworks.
You could, for example, add a custom endpoint path inside your app where you make sure that the only accepted clients come from the same, private IP subnet of your cluster, either without a token (not recommended) or with a specific semi-fixed one that you generate and control, so that you would send a request to something like this from your crons: go-api.go-apps.svc.cluster.local:8080/api/v1/callWithNoAuth
I am creating a new answer as I feel I have more points to contribute to this.
So, what I eventually did end up doing is creating a middle-ware for internal API calls. Inside this middleware, I authorize the caller in middleware i.e. check whether it is from "xyz-service:port".
I found that the need to use a 3rd party authenticator was overkill and using a token in code was riskier.
Since all the services except for the ingress is ClusterIP, No one can access it from outside directly.
Thanks to #LeoD's answer. I gained confidence using this method.
P.S. Simply service-name:port can suffice
eg: http://myservice:4000/api

OWIN Authentication Failing - Web API

I have some Web API applications that uses OWIN for authentication. Currently they are hooked up to Google and Facebook. I have them installed in multiple environments (local, dev, test, etc). Recently ALL of my applications in my development environment started failing. When trying to authenticate I would get a response back "access_denied". The URL would look like this:
https://{mydevserver}/{mywebapiapp}/#error=access_denied
The same code base works locally as well as in my test environment.
I tried using the same project (just adding redirect uris and orgins) as well as creating a new project.
I also updated my test environment to use the dev project (id and secret).
Nothing seems to have changed on the server recently. But it seems to be environment specific (because multiple applications are affected as well as multiple providers).
Are there any logging techniques I can use to drill down to a more detailed error message? Any tips or hints for what to try next?
The fix was a bit of an odd one. I had to log into my server, open up a browser and connect to a web page (any page). After doing so it started working again.

Need suggestions on security design for a web application

i'm designing a security module for a web application using spring security . There are 3 separate wars(3 Apps)using separate login, deployed in a JBOSS Server.
The requirement is , If the user is authenticated in one app then he should be able to access other applications without login . Is it possible to share the security context between the web application( different wars not in a single EAR ).
We discussed about the SSO , but we are trying to achieve this with spring security and with support of the App server . Is there any way ? Please provide your valuable suggestions and inputs.
If you need more information, please let me know.
The easiest way is to employ usual Spring Security authentication (e.g. form-based with username/password) and enable the remember-me feature.
As long as all three applications are deployed on the same domain (and can therefore share their cookies), the remember-me feature will work seamlessly for all of them, i.e. once user authenticates at any of the applications she will be able to access the others without need for re-authentication.
This of course doesn't address issues like single logout, but that doesn't seem to be your aim anyway.
You can set this up in a short time and don't need and third party SSO components. Although relaying on standard SSO protocols and dedicated technologies tends to be a more secure option.
I've done this recently with SSO and Spring Security however I wrote our own security filter to be used which grabs the HttpServletRequest.getRemoteUser() value provided by the SPNEGO filter. One thing with SSO: most mechanisms use Kerberos which only really works in local desktop environments. It is possible to write a fallback mechanism which will redirect the user to a login page but then you still have your issue at hand.
Another option would be to repackage your applications as an EAR (see here).

Ofbiz framework repeatedly prompts for login credentials

I am using ofbiz for an e-commerce site and I have recently migrated from EC2 type amazon servers to VPC type servers provided by Amazon.
After migrating I often see ofbiz asking for login credentials again and again before performing any task. In other words, I have to provide my credentials again and again to accomplish any single task.
Google couldn't help me with this neither the ofbiz forums, any hint if not the exact solution would also help.
This sort of problem often requires some research and testing, but I'd start with looking at session related issues like cookies (for plain HTTP) and HTTPS sessions, and also that the jsessionid is included in the URL when switching between HTTP and HTTPS.
It may be that something in the network is different between the plain EC2 and the private cloud and that is causing issues with maintaining the session. I don't know a lot about VPC on AWS, so can't comment on more detailed things to look into there.

Setup kerberos delegation automatically

I have a web app that uses some backend servers (UNC, HTTP and SQL). To get this working I need to configure ServicePrincipalNames for the account running the IIS AppPool and then allow kerberos delegation to the backend services.
I know how to configure this through the "Delegation" tab of the AD Users and Computers tool.
However, the application is going to be deployed to a number of Active Directory environments. Configuring delegation manually has proved to be error prone and debugging the issues misconfiguration causes is time consuming. I'd like to create an installation script or program that can do this for me.
Does anyone know how to script or programmatically set constrained delegation within AD?
Failing that how can I script reading the allowed services for a user to validate that it has been setup correctly?
OK, after much digging on the internet and some testing, I've got a way forward.
The following code is c#.
Setting an SPN for a user or computer can be achieved via the setspn utility.
Alternatively, the following C# code can do the same:
DirectoryEntry de = new DirectoryEntry("LDAP://"+usersDN);
if (!de.Properties["servicePrincipalName"].Contains(spnString))
{
de.Properties["servicePrincipalName"].Add(spnString);
de.CommitChanges();
}
To set constrained delegation:
if (!de.Properties["msDS-AllowedToDelegateTo"].Contains(backendSpnString))
{
de.Properties["msDS-AllowedToDelegateTo"].Add(backendSpnString);
de.CommitChanges();
}
If the user has had non-constrained delegation enabled, you may need to turn this off before enabling constrained - but I didn't fully test this scenario.

Resources