0
votes

I am facing an issue to login into the Jenkins using Sharepoint client webpart.

Security on Jenkins Side : using the Azure AD plugin, user can now login using the Office 365 credentials.

On the cloud: Created an App Registration with the redirect URI as - https://{JenkinsDomain}/securityRealm/finishLogin

Now I am creating a client WebPart, and I am trying to access the URL - https:///api/json?tree=jobs[name,color] from the web part, it says 'Error 403 - Forbidden', although when I try the same URL from new tab, it gives me response.

Things I've tried:

const msalConfig = {
  auth: {
    clientId: "api://<client>/",
    // authority: "https://login.microsoftonline.com/common",
    authority : "https://login.microsoftonline.com/<tenantID>/",
    scopes: ['https://graph.windows.net/Directory.Read.All'],
    redirectUri : 'https://<tenantName>.sharepoint.com/'
  }
};
var userAgentApplication = new Msal.UserAgentApplication(msalConfig)

userAgentApplication.loginPopup().then(function (id_token) {
  console.log(id_token);
  var user = userAgentApplication.getAccount();
  console.log(user);
  if (user) {

  }
})

This code gives me error :

AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: 'api://{clientID}/'.

Is there any way that I can access Jenkins API with Azure AD enabled through the Client Web Part? Any help is appreciated. Thanks

1
Did you tried with providing the matched redirect URI on your application in azure portal?Md Farid Uddin Kiron
your AD's redirect URL is https://{JenkinsDomain}/securityRealm/finishLogin but in the code you are using https://<tenantName>.sharepoint.com/ which is why you get the STS errorSaravanan
@Saravanan I tired the 'https://{JenkinsDomain}/securityRealm/finishLogin' url too, yet it showed the same error. Also I wanna acheive something like this, if that's possible from javascript - stackoverflow.com/questions/57408352/… , thanks!Abhishek Pal
@MdFaridUddinKiron Yes tried, but it did not work.Abhishek Pal
Are you trying to access the Jenkins REST API from the Javascript ?Saravanan

1 Answers

1
votes

Below given are the steps that we follow to invoke a Jenkins REST API from within the code, be it Javascript / Java.

  1. Login to the Jenkins Server using the SSO or Jenkins Login (In your case your AD will authenticate you and take you to the home page)
  2. Once logged-in, go to Manage Users
  3. In the manage users, either for a selected user or for a super admin user, we have to choose the settings which takes to the user details page. we normally have a admin user for which we configure the tokens.
  4. In that page, we have to provide a name for the token and generate a new token.
  5. This token is to be copied and placed in a secure location
  6. Once done, save the profile
  7. Now, from the javascript / java code, use the format of usename:token and get the base64 string of this value. Example java code snippet is given below

    String secureToken = Base64.getEncoder().encodeToString((user + ":" + key).getBytes());

  8. After this, set the secureToken in the Authorization header like the one given below for Java

    httpGet.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + secureToken);

  9. Now, you can make calls to the Jenkins REST API like getting build statistics, triggering a build etc with this approach.

I will gather some useful links from Jenkins and post for further reading because the security token's are to be securely used and they have to rotated after some time for security reasons (since these will make this a very long post, i am skipping these points here).

I have the below links which will give bit more details

https://wiki.jenkins.io/display/JENKINS/Remote+access+API

https://www.decodingdevops.com/jenkins-authentication-token-jenkins-rest-api/

Also, I got this code that we used long back for node.js to talk to jenkins, hope this may be useful for you

const options = {
    hostname: process.env.JENKINS_HOST,
    port: process.env.JENKINS_PORT,
    path: `${jenkinsBuildUrl}?param1=${param1}&param2=${params.Key}&operation=${operation}`,
    method: "POST",
    headers: {
        'Authorization': 'Basic '+ Buffer.from('admin'+':'+process.env.AUTH_TOKEN).toString('base64')
    }
};

const jr = https.request(options, jres => {
    jres.on("data", chunk => {
        console.log(`BODY: ${chunk}`);
    });
    jres.on("end", () => {
        console.log("Request completed with no data.");
    });
});
jr.on("error", e => {
    console.log(
        `Something went wrong when triggering the build in Jenkins Server in the current request: ${e.message}`
    );
});
jr.end();

HTH