How to configure corporate HTTP proxy with authentication - docusignapi

I am testing the DocuSign API Client for Java.
The problem is that the testing environment as well as the production environment is behind a corporate Proxy that needs authentication (username + password, not just host + port).
But I see no way to configure the DocuSign ApiClient.
I only can set up http.proxyHost and http.proxyPort, but no http.proxyUser and http.proxyPassword.
System.getProperties().put("http.proxyHost", host);
System.getProperties().put("https.proxyHost", host);
System.getProperties().put("http.proxyPort", String.valueOf(port));
System.getProperties().put("https.proxyPort", String.valueOf(port));
System.getProperties().put("http.proxyUser", user);
System.getProperties().put("http.proxyPassword", password);
Authenticator.setDefault(
new Authenticator() {
#Override
public PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType() == Authenticator.RequestorType.PROXY) {
System.out.println(getRequestingHost() + ":" + getRequestingPort() + " -> " + getRequestingURL());
return new PasswordAuthentication(user, password.toCharArray());
}
return null;
}
}
);
Setting the Authenticator.setDefault() works with default java http client, but it does not show any effect when using the DocuSign ApiClient.

yes, you can do that using:
For HTTPS (recommended): https.proxyHost, https.proxyPort, https.proxyUser and https.proxyPassword
For HTTP: http.proxyHost, http.proxyPort, http.proxyUser and http.proxyPassword
this was added in version 2.9.0 of the client which was released in Feb, so if you have that or later - you should be good

I have updated from 2.8.0 to 2.9.0.
I have tested it but currently I still get the same exception com.sun.jersey.api.client.ClientHandlerException: java.io.IOException: Unable to tunnel through proxy. Proxy returns "HTTP/1.0 407 Proxy Authentication Required"
I used this code as recommended in the last answer:
System.getProperties().put("http.proxyHost", host);
System.getProperties().put("https.proxyHost", host);
System.getProperties().put("http.proxyPort", String.valueOf(port));
System.getProperties().put("https.proxyPort", String.valueOf(port));
System.getProperties().put("http.proxyUser", user);
System.getProperties().put("https.proxyUser", user);
System.getProperties().put("http.proxyPassword", password);
System.getProperties().put("https.proxyPassword", password);
The problem is that http.proxyUser and http.proxyPassword don't get recognized by the DocuSign API Client.

Related

Basic authentication for website to secure site login and API access

I'm looking at the security model of a website that's being developed. After researching the web i have found that there are several security models to secure websites i.e. Basic Auth, JWT ...
At the moment, SSL is not enabled as still in dev. Website has a login page and communicates via API's (including login and logout). On the login page, as a test, I have attempted to log in with false details, and then I have looked at the developer tools to identify the security mechanism and found the following screenshots. I think the site is using basic authentication, though I noted that the email / password is not encoded and is using a custom login form. Could someone confirm if it is basic authentication being utilised?
Developer Tools Images
[Request Header Image][2]
UPDATE:
I discovered that once the user is authenticated by email/password, I should have posted the screenshots as this is where keys are returned. In the below screenshot a bidder token and bidder secret is sent back to client. I think these are generated through crypto on backend. So I don't think its JWT, but is this a suitable way in creating keys and not sending in header but in response body?
Network tab after user logged in
Login Form Code :
{
/* prepare ui */
progress.classList.remove('hide');
login_btn.innerText = 'Logging In';
login_btn.setAttribute('disabled', true);
/* make http request */
var http = new XMLHttpRequest();
var url = SERVER + '/api/bidder/login';
var body = {
email: email.value,
password: password.value
};
http.open('POST', url, true);
http.setRequestHeader('Content-type', 'application/JSON');
http.onreadystatechange = function () { //Call a function when the state changes.
if (http.readyState == 4 && http.status == 200) {
var res = JSON.parse(http.responseText);
if (res.status) {
localStorage.setItem("bidData", JSON.stringify(res.data));
window.location.href = window.location.href.replace('login.html','');
} else {
Toast.show('Danger', res.message);
}
/* reset ui */
progress.classList.add('hide');
login_btn.innerText = 'Log In';
login_btn.removeAttribute('disabled');
}
}
http.send(JSON.stringify(body));
}
When you use basic access authentication, credentials wouldn't be loaded in a request payload. They reside in an authorization header like "Authorization: Basic ~some credential here~".
So if you neither see this authorization header in your request nor a popup like below on the website, basic access authentication is not enabled.
Spring security is the most basic authentication in the Spring project
If you want to enable Spring security, the first thing you must add is the spring security library to your project. After adding it, you create a class to configure Spring security.
A function in the class config for Spring security.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/api/statistical/**",
"/static/**",
"/webjars/**",
"/img/**",
"/css/**",
"/js/**",
"/api/diary/**")
.permitAll()
.antMatchers("/api/auth/**")
.permitAll()
.antMatchers("/api/user/checkUsernameAvailability", "/api/user/checkEmailAvailability")
.permitAll()
.antMatchers(HttpMethod.GET, "/api/users/**") //, "/api/polls/**"
.permitAll()
.anyRequest()
.authenticated();

Accessing Skype for Business API (UCWA) : HTTP 403 / Forbidden

I'm trying to connect to & use Skype for Business API (UCWA) following this procedure, using a Node.js test script.
I've registered a test app in Azure AD and checked all permissions concerning Skype for Business Online.
I'm doing this (simplified):
var adal = require('adal-node');
var https = require('https');
var clientId = 'a5cbbd......cc4a1'; // = app ID
var clientSecret = 'IOSDk1......LJ6vE=' // test key from Azure AD
var context = new adal.AuthenticationContext('https://login.windows.net');
// 'Autodiscover' step
// (callRestAPI() makes an HTTPS request using https.request() and returns results as JSON)
callRestAPI('webdir.online.lync.com', 443, '/autodiscover/autodiscoverservice.svc/root', 'GET', null /* no specific headers */, function(err, res) {
if (err) { console.log(err); return err; }
// extract discovered domain (I get something like https://webdir1e.online.lync.com)
let regex = new RegExp('^(https?://[^/]*)', 'g');
let sfbDiscoveredDomain = regex.exec(response._links.user.href);
sfbDiscoveredDomain = sfbDiscoveredDomain[1];
// 'Acquire token' step
context.acquireTokenWithClientCredentials(sfbDiscoveredDomain, clientId, clientSecret, function(err, res) {
if (err) { console.log(err); return err; }
regex = new RegExp('^https?://([^/]*)', 'g');
let sfbHost = regex.exec(res.resource);
sfbHost = sfbHost[1]; // here I get something like 'webdir1e.online.lync.com'
// 'Resending an autodiscovery request with the bearer token' step
callRestApi(sfbHost, 443, '/autodiscover/autodiscoverservice.svc/root/oauth/user', 'GET', {'Authorization': 'Bearer '+res.accessToken}, function(err, res) {
if (err) { console.log(err); return err; }
console.log(res);
});
});
});
The last step (resending an autodiscovery request) always fails with error HTTP 403/Forbidden.
There is an additional interesting response header:
'x-ms-diagnostics': '28070;source="AM41E00EDG01.infra.lync.com";reason="Service does not allow a cross domain request from this origin."'
...but I still don't understand why this error occurs.
I've played with additional headers seen here and there in various code samples (X-Ms-Origin and Host), with no luck.
This issue (Service does not allow a cross domain request from this origin.) is mostly caused by the "Cross-Origin Resource Sharing (CORS)" and that the address which is requesting the access isn´t "whitelisted".
An Skype for Business Administrator can configure that via (more info's here) when the server is on premises (see StackOverflow question here):
$x = New-CsWebOrigin -Url "https://apps.contoso.com"
Set-CsWebServiceConfiguration -Identity "{YOUR_IDENTITY}" -CrossDomainAuthorizationList #{Add=$x}
However as your Skype for Business isn´t on premises (its online) I assume there is nothing you can do as this section is mostly controlled by the cloud admins from Microsoft.
However as UCWA is supported with Skype for Business online I assume there is something wrong on your side. Did you checked if the application is correctly registered as explained here? If yes a fiddler trace might be useful to see what caused that issue.

Angular 2 Azure Active Directory authentication via ADAL

I'm trying to authenticate an Angular 2 client app (that also uses the Ionic framework) against an Azure Active Directory, and then talk to a .NET Web API.
However I am getting the following error after login:
Login error: AADSTS65001: The user or administrator has not consented to use the application with ID '1cdd3510-c720-44b8-9531-b880f51aa3dd'. Send an interactive authorization request for this user and resource.
When I logged in for the first time I was asked for permission, which I accepted. I can see most of the application, except for the parts reliant on the API. The issue can be resolved by removing the [Authorize] attribute on the API controllers, but this would leave it completely open.
The client application is set up in the Azure Portal as so:
Client application permissions
I enabled all permissions in a last-ditch attempt to get it to work, I have also enabled access to the API application.
My auth service is configured as follows:
private version: string = "-dev";
private config: any = { // web browser
tenant: "***.onmicrosoft.com",
clientId: "********-****-****-****-************", // Client ID
postLogoutRedirectUri: window.location.origin,
endpoints: {
["https://***" + this.version + ".azurewebsites.net/api"]: "https://***.onmicrosoft.com/api"
},
cacheLocation: "localStorage"
};
private base: string = "https://***.onmicrosoft.com";
private appId: string = this.base + "/interface";
private apiId: string = this.base + "/api";
private appUri: string = "https://***" + this.version + ".azurewebsites.net"
private apiUri: string = this.appUri + "/api";
private authority = "https://login.windows.net/***.onmicrosoft.com"; // Authority from azure
private nativeClientId = "********-****-****-****-************"; // Ionic app ID
private redirectUri = "http://***app"; // Ionic app URI
private currentUser: any; // Object representing the current user
private authContext: any; // Auth context from adal.js
And the part of the service that is throwing the error above is:
this.authContext.acquireToken(endpoint, (error, token) => {
if (error || !token) {
console.log("Login error: " + error);
return;
} else {
resolve(token);
}
});
This issue has been going on for quite a while so any help would be much appreciated.
Did you register native application with Web API and vice versa, as shown in https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-app-registration#register-a-web-api . Also add Scope in your .Net web api call with OpenID

Set production URL Jhipster

When I package for production, and I want to recover my password, url which leads me to my mail it is incorrect.
http://localhost:8095/af/#/reset/finish?key=03106204321257101265
The right thing would be
https://www.XXX.es/af/#/reset/finish?key=03106204321257101265
I do not see any property in .yml and not to the steps to put the base url me I need.
Jhipster 3.4.2
Thanks for the help
Set server.port and server.address properties in your application-prod.yml file. Please refer to Spring Boot doc for details and alternate ways of setting these.
It seems that dynamically form, but when it is on the server also takes as "request.getServerName()"= "localhost"
Do not use the built-in Jhipster Tomcat, but other external.
public ResponseEntity<?> requestPasswordReset(#RequestBody String mail, HttpServletRequest request) {
System.out.println("scheme"+ request.getScheme());
System.out.println("server name" + request.getServerName());
System.out.println("server port" + request.getServerPort());
System.out.println("context path"+ request.getContextPath());
return userService.requestPasswordReset(mail)
.map(user -> {
String baseUrl = request.getScheme() +
"://" +
request.getServerName() +
":" +
request.getServerPort() +
request.getContextPath();
mailService.sendPasswordResetMail(user, baseUrl);
return new ResponseEntity<>("e-mail was sent", HttpStatus.OK);
}).orElse(new ResponseEntity<>("e-mail address not registered", HttpStatus.BAD_REQUEST));
}

JavaMail from OpenShift: javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted

I have an application deployed on OpenShift, from which I need to send email to and from a single Google account.
With the application deployed locally, it works perfectly; however, when trying the same with the application deployed on OpenShift, I get the following authorisation error:
19:23:16,265 ERROR [stderr] (default task-2) javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at
https://support.google.com/mail/answer/14257 wn10sm1673177wjc.46 - gsmtp
19:23:16,266 ERROR [stderr] (default task-2) at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:843)
Everything else works perfectly in my OpenShift deployment.
This is what my implementation looks like:
Properties props = new Properties();
String host = "smtp.gmail.com";
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", myEmail);
props.put("mail.smtp.password", password);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props);
MimeMessage message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress(myEmail));
InternetAddress toAddress = new InternetAddress(myEmail);
message.addRecipient(Message.RecipientType.TO, toAddress);
message.setSubject(title);
message.setText(msg);
Transport transport = session.getTransport("smtp");
transport.connect(host, myEmail, password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
catch (AddressException ae) {
ae.printStackTrace();
}
catch (MessagingException me) {
me.printStackTrace();
}
I have tried the following solutions proposed in the URL from the exception trace and as answers to other SO questions:
Allowed less secure apps is ON in Google settings
Tried with both user#gmail.com and user for the sender
Allowed access to the Google account from https://accounts.google.com/b/0/DisplayUnlockCaptcha
The 2-step verification is OFF in Google settings
Waited >10 minutes between tries, to allow for some "cool-off" between unsuccessful authorisations

Resources