Im tring to user the DocuSign api/sdk to send a document for someone to sign. The examples say something like:
//.NET
APIServiceSoapClient apiService = new APIServiceSoapClient();
apiService.ClientCredentials.UserName.UserName = "Your DocuSign UserName here";
apiService.ClientCredentials.UserName.Password = "Your DocuSign Password here";
Which I of course have tried but its not working.
I get the following error:
Security requirements are not satisfied because the security header is not present in the incoming message.
Ive tried
var username = "myemail";
var pass = "mypass";
var iteratorKey = "iteratorkey";
APIServiceSoapClient apiService = new APIServiceSoapClient();
apiService.ClientCredentials.UserName.UserName = username;
//also tried ...UserName = "[" + iteratorKey + "]" + username;
apiService.ClientCredentials.UserName.Password = pass;
Is this not where all security requirements are met? maybe? Using APIService not DSAPIService if that makes a difference.
I ended up having to use a different way to pass in the credentials. Which I found somewhere else. Im still not sure how to correctly use the other method I tried though so if anyone knows how to use the other method it would be great just because the code is neater and easier to follow.
string auth = #"<DocuSignCredentials>
<Username>email</Username>
<Password>pass</Password>
<IntegratorKey>key</IntegratorKey>
</DocuSignCredentials>";
DSAPIServiceSoapClient apiService = new DSAPIServiceSoapClient();
using (var scope = new System.ServiceModel.OperationContextScope(apiService.InnerChannel))
{
var httpRequestProperty = new System.ServiceModel.Channels.HttpRequestMessageProperty();
httpRequestProperty.Headers.Add("X-DocuSign-Authentication", auth);
System.ServiceModel.OperationContext.Current.OutgoingMessageProperties[System.ServiceModel.Channels.HttpRequestMessageProperty.Name] = httpRequestProperty;
EnvelopeStatus envStatus = apiService.CreateAndSendEnvelope(envelope);
return envStatus.EnvelopeID;
}
There are two ways to pass member credentials through DocuSign's SOAP API (as opposed to the newer REST API):
SOAP Header via WS-Security UsernameToken
HTTP Header via a custom field “X-DocuSign-Authentication”
The Account Management API only supports the HTTP Header authentication method, while all others can support either method.
Additionally, the DocuSign SOAP API has two API end points: API.asmx and DSAPI.asmx. The API.asmx end point requires the WS-Security UsernameToken in the SOAP header authentication. The DSAPI.asmx and AccountManagement.asmx end points require the HTTP Header authentication method.
Related
I am integrating DocuSign with salesforce using Rest API in order to send the envelopes.
Before sending any envelopes I was working on an Implicit grant in order to generate a token but I am not sure what is the right way to get the token.
I am using the GET method but I am getting the response in HTML format.
public class SendDocumentsWithDocuSign {
public void test(){
String accountID = 'a6e74d5a-****-****-****-28f3bec67ccf';
String userName = 'f2326e06-****-****-****-a1aee682da08';
String passWord = 'password#123';
String integrationKey = 'b19b477c-****-****-a8a5-8ff88ea771cc';
String templateID = '5259faf7-****-****-a493-ba19ce5d633c';
String redirectURL='https://www.salesforce.com';
//Request the implicit grant
String TOKEN_URL = 'https://account-d.docusign.com/oauth/auth?response_type=token&scope=signature&client_id='+integrationKey+'&redirect_uri='+redirectURL;
String authenticationHeader =
'<DocuSignCredentials>' +
'<Username>' + userName+ '</Username>' +
'<Password>' + password + '</Password>' +
'<IntegratorKey>' + integrationKey + '</IntegratorKey>' +
'</DocuSignCredentials>';
HttpRequest httpreq = new HttpRequest();
HttpResponse httpres = new HttpResponse();
Http httpCall = new Http();
httpreq.setEndpoint(TOKEN_URL);
httpreq.setMethod('GET');
//httpreq.setHeader('X-DocuSign-Authentication', authenticationHeader);
httpreq.setHeader('Content-Type', 'application/json');
httpreq.setHeader('Accept', 'application/json');
httpres = httpCall.send(httpreq);
System.debug(httpres.getHeaderKeys());
System.debug(httpres.getHeader('X-DocuSign-TraceToken'));
System.debug(httpres.getHeader('Set-Cookie'));
System.debug(httpres.getBody());
}
}
I am getting the below Output.
[32]|DEBUG|(X-DocuSign-Node, X-Content-Type-Options, X-DocuSign-TraceToken, Pragma, Date, X-Frame-Options, Strict-Transport-Security, Cache-Control, Content-Security-Policy, Set-Cookie, ...)
[33]|DEBUG|4d4cac98-7cc9-4b3e-a1fe-c12e871b7065
[34]|DEBUG|__RequestVerificationToken=ARFea2sGN3iGpAjBGHGwCJcB0; path=/; secure; HttpOnly
[35]|DEBUG|
input name="__RequestVerificationToken" type="hidden" value="ARFea2sGN3iGpAjBGHGwCJcAAAAA0"
I want to fetch the access token to call the REST API as given in the DocuSign document. https://developers.docusign.com/platform/auth/implicit/implicit-get-token
To use the DocuSign APEX toolkit, you need to follow the toolkit's authentication methods since that's the only way to use the (needed) integration key from the APEX toolkit.
See the toolkit's authentication instructions.
If you're not using the APEX toolkit then you need to work within the capabilities of SalesForce. Named Credentials is one approach. Here's another.
This is rather a silly question but I can't seem to figure it out. I'm building a flutter app that communicates to an API and in order for the user to be authenticated it sends an token.
Whenever the user logs in I save the token in the Shared Preferences and then when I make an request add the token to the headers or in this case I need it in the url.
However, whenever I concatenate the strings: the server url and the token it adds extra "" to the token. something like:
http://10.0.2.2:64342/chatHub?access_token="token-value"
instead of
http://10.0.2.2:64342/chatHub?access_token=token-value
here's the code:
var preferences = await SharedPreferences.getInstance();
token = preferences.getString(token_key);
var url = '$serverURl?access_token=$token';
As far as I understand your question, I would like to answer it.
That's not possible!
var serverURl = 'http://10.0.2.2:64342/chatHub';
var token = 'token-value';
var url = '$serverURl?access_token=$token';
print(url);
It just prints the correct one!
You can check the string that is stored in the SharedPreferences! That maybe with quotes.
Okay, I figured it out. Since I was sending only the token from the API. I was receiving it with the "" in it.
Instead I now send a json with the token, like: { "token": "token_value"} and then decode it to get the actual value. So when I store it the shared preferences it doesn't keep the "".
So in the backend:
return Ok(new {token = generatedToken});
and in dart
var tokenJson = json.decode(response.body);
var token = tokenJson['token'];
preferences.setString(token_key, token);
Thanks to everyone that helped :)
I'm trying to query github's api with a token. Github's api accepts generated tokens provided that they're sent as a basic auth header.
The API do not return HTTP 401 if the call is made without auth which means if one wants to query their api using Basic Auth, one must fill the header pre-emptively rather than doing a round trip.
I'm now trying to query the API using libsoup and Gjs.
I have noticed the SoupAuthManager has a function that seems to match perfectly what I need (soup_auth_manager_use_auth here) but can't find a way to invoke it.
This can be used to "preload" manager 's auth cache, to avoid an extra HTTP round trip in the case where you know ahead of time that a 401 response will be returned
This is what I currently use, but it does not work as the SoupAuthManager is a private object of the session; and has therefore no effect on the actual behaviour of the program
let httpSession = new Soup.Session();
let authUri = new Soup.URI(url);
authUri.set_user(this.handle);
authUri.set_password(this.token);
let message = new Soup.Message({method: 'GET', uri: authUri});
let authManager = new Soup.AuthManager();
let auth = new Soup.AuthBasic({host: 'api.github.com', realm: 'Github Api'});
authManager.use_auth(authUri, auth);
httpSession.queue_message(message, ...);
Are there other methods I could use to force Basic Auth on the first roud trip? or are there other library I could use from gjs to call github's API and force the basic auth?
I found the solution. To link the authorisation to the session, one can use the add_feature function. Now this is defined here but it turns out calling it directly doesn't work
this._httpSession.add_feature(authManager)
instead it seems to work if called like that:
Soup.Session.prototype.add_feature.call(httpSession, authManager);
finally, the github api rejects any call without a user agent, so I added the following:
httpSession.user_agent = 'blah'
the final code looks like:
let httpSession = new Soup.Session();
httpSession.user_agent = 'blah'
let authUri = new Soup.URI(url);
authUri.set_user(this.handle);
authUri.set_password(this.token);
let message = new Soup.Message({method: 'GET', uri: authUri});
let authManager = new Soup.AuthManager();
let auth = new Soup.AuthBasic({host: 'api.github.com', realm: 'Github Api'});
Soup.Session.prototype.add_feature.call(httpSession, authManager);
httpSession.queue_message(message, function() {...});
I created an account in the Docusign Sandbox to evaluate the product. My main goal is to create a signing group but before that I would like to get the list of signing groups with RestSharp.
[EDIT]
docusign.configureApiClient("https://demo.docusign.net/restapi");
var login = docusign.LoginDocusign(USERNAME, PASSWORD);
var client = new RestClient(login.BaseUrl);
var request = new RestRequest("signing_groups", Method.GET);
string authHeader = "{\"Username\":\"" + USERNAME + "\", \"Password\":\"" + PASSWORD + "\", \"IntegratorKey\":\"" + INTEGRATOR_KEY + "\"}";
request.AddHeader("X-DocuSign-Authentication", authHeader);
IRestResponse response = client.Execute(request);
var content = response.Content;
Debug.WriteLine(content);
However the content returns
error code : "ACCOUNT_LACKS_PERMISSIONS"
message: "This Account lacks sufficient permissions."
I thought demo accounts have almost the same permissions as a premium account. Is there a setting somewhere to enable this?
I am certain that the authentication is correct when I request for list of groups, the content returns all of my groups.
var request = new RestRequest("groups", Method.GET);
I'm not familiar with RestSharp, but my suspicion is that there's a problem with the request.
To diagnose: first start with making a call to DocuSign and use the Request Log facility to see what is being sent.
If the incoming request can't be matched to your account, or fails some initial filters, then the request will not reach your account. In that case, use requestb.in (free) to see what you're sending.
Also, I don't see where you are requesting the accountId and base URL from DocuSign. (Using https://demo.docusign.net/restapi/v2/login_information)
That's the first step for an API integration since you can't predict which platform the user's account is running on.
I am trying to set up a C# console app that can send notifications/reminders to users via Skype for Business online from a generic AD account. I was excited to see the other day that according to this page, UCWA is now supported in Skype for Business online: https://msdn.microsoft.com/en-us/library/office/mt650889.aspx.
I've been trying to follow this tutorial to get this set up: https://msdn.microsoft.com/en-us/library/office/mt590891(v=office.16).aspx. So far I haven't really had much luck... I have my application set up in Azure AD but I get stuck at the "Requesting an access token using implicit grant flow" step of that article (not 100% certain I'm taking the correct actions before that either)... so far I have this:
string clientId = "xxxxxxxx"
string resourceUri = "https://webdir.online.lync.com";
string authorityUri = "https://login.windows.net/common/oauth2/authorize";
AuthenticationContext authContext = new AuthenticationContext(authorityUri);
UserCredential cred = new UserCredential("username", "password");
string token = authContext.AcquireToken(resourceUri, clientId, cred).AccessToken;
var poolReq = CreateRequest("https://webdir.online.lync.com/autodiscover/autodiscoverservice.svc/root", "GET",token);
var poolResp = GetResponse(poolReq);
dynamic tmp = JsonConvert.DeserializeObject(poolResp);
string resourcePool = tmp._links.user.href;
Console.WriteLine(resourcePool);
var accessTokenReq = CreateRequest("https://login.windows.net/common/oauth2/authorize"
+ "?response_type=id_token"
+ "&client_id=" + clientId
+ "&redirect_uri=https://login.live.com/oauth20_desktop.srf"
+ "&state=" + Guid.NewGuid().ToString()
+ "&resource=" + new Uri(resourcePool).Host.ToString()
, "GET",token);
var accessTokenResp = GetResponse(accessTokenReq);
my GetResponse and CreateRequest methods:
public static string GetResponse(HttpWebRequest request)
{
string response = string.Empty;
using (HttpWebResponse httpResponse = request.GetResponse() as System.Net.HttpWebResponse)
{
//Get StreamReader that holds the response stream
using (StreamReader reader = new System.IO.StreamReader(httpResponse.GetResponseStream()))
{
response = reader.ReadToEnd();
}
}
return response;
}
public static HttpWebRequest CreateRequest(string uri, string method, string accessToken)
{
HttpWebRequest request = System.Net.WebRequest.Create(uri) as System.Net.HttpWebRequest;
request.KeepAlive = true;
request.Method = method;
request.ContentLength = 0;
request.ContentType = "application/json";
request.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken));
return request;
}
accessTokenResp is an office online logon page, not the access token I need to move forward... so I'm stuck. I've tried quite a few variations of the above code.
I've been scouring the net for more examples but can't really find any, especially since UCWA support for Office 365 is so new. Does anyone have an example of how to do what I am trying to do or can point me to one? Everything I've found so far hasn't really even been close to what I'm trying. I can't use the Skype for Business client SDK unfortunately either as it doesn't meet all of my requirements.
I came to a working solution using ADAL (v3), with the help of steps outlined at
Authentication using Azure AD
Here the steps, which involve requesting multiple authentication tokens to AAD using ADAL
Register your application, as Native Application, in Azure AD.
Perform autodiscovery to find user's UCWA root resource URI.
This can be done by performing a GET request on
GET https://webdir.online.lync.com/Autodiscover/AutodiscoverService.svc/root?originalDomain=yourdomain.onmicrosoft.com
Request an access token for the UCWA root resource returned in the autodiscovery response, using ADAL
For instance, your root resource will be at
https://webdir0e.online.lync.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=yourdomain.onmicrosoft.com
you'll have to obtain a token from AAD for resource https://webdir0e.online.lync.com/
Perform a GET on the root resource with the bearer token obtained from ADAL
GET https://webdir0e.online.lync.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=yourdomain.onmicrosoft.com
This will return, within the user resource, the URI for applications resource, where to create your UCWA application. This in my case is:
https://webpoolam30e08.infra.lync.com/ucwa/oauth/v1/applications
Residing then in another domain, thus different audience / resource, not included in the auth token previously obatained
Acquire a new token from AAD for the host resource where the home pool and applications resource are (https://webpoolam30e08.infra.lync.com in my case)
Create a new UCWA application by doing a POST on the applications URI, using the token obtained from ADAL
Voilá, your UCWA application is created. What I notice at the moment, is that just few resources are available, excluding me / presence. So users' presence can be retrieved, but self presence status can't be changed.
I've been able however to retrieve my personal note, and the following resources are available to me:
people
communication
meetings
Show me some code:
Function to perform the flow obtaining and switching auth tokens
public static async Task<UcwaApp> Create365UcwaApp(UcwaAppSettings appSettings, Func<string, Task<OAuthToken>> acquireTokenFunc)
{
var result = new UcwaApp();
result.Settings = appSettings;
var rootResource = await result.Discover365RootResourceAsync(appSettings.DomainName);
var userUri = new Uri(rootResource.Resource.GetLinkUri("user"), UriKind.Absolute);
//Acquire a token for the domain where user resource is
var token = await acquireTokenFunc(userUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped));
//Set Authorization Header with new token
result.AuthToken = token;
var usersResult = await result.GetUserResource(userUri.ToString());
//
result.ApplicationsUrl = usersResult.Resource.GetLinkUri("applications");
var appsHostUri = new Uri(result.ApplicationsUrl, UriKind.Absolute).GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped);
//Acquire a token for the domain where applications resource is
token = await acquireTokenFunc(appsHostUri);
//Set Authorization Header with new token
result.AuthToken = token;
//
var appResult = await result.CreateApplicationAsync(result.ApplicationsUrl, appSettings.ApplicationId, appSettings.UserAgent, appSettings.Culture);
return result;
}
Usage code ato retrieve OAuth tokens using ADAL
var ucSettings = new UcwaAppSettings
{
UserAgent = "Test Console",
Culture = "en-us",
DomainName = "yourdomain.onmicrosoft.com",
ApplicationId = "your app client id"
};
var acquireTokenFunc = new Func<string, Task<OAuthToken>>(async (resourceUri) =>
{
var authContext = new AuthenticationContext("https://login.windows.net/" + ucSettings.DomainName);
var ar = await authContext.AcquireTokenAsync(resourceUri,
ucSettings.ApplicationId,
new UserCredential("myusername", "mypassword"));
return new OAuthToken(ar.AccessTokenType, ar.AccessToken, ar.ExpiresOn.Ticks);
});
var app = await UcwaApp.Create365UcwaApp(ucSettings, acquireTokenFunc);
It should be of course possible to avoid hard-coding username and password using ADAL, but this was easier for PoC and especially in case of Console Application as you asked
I've just blogged about this using a start-to-finish example, hopefully it will help you. I only go as far as signing in, but you can use it with another post I've done on sending IMs using Skype Web SDK here (see day 13 and 14) and combine the two, it should work fine.
-tom
Similar to Massimo's solution, I've created a Skype for Business Online C# based console app that demonstrates how to sign and use UCWA to create/list/delete meetings and change user presence. I haven't gotten around to extending it to send IM's, but you're certainly welcome to clone my repository and extend it to your needs. Just drop in your Azure AD tenant name and native app ID into the code.
I think they just turned this on today - I was doing something unrelated with the Skype Web SDK samples and had to create a new Azure AD app, and noticed that there are two new preview features for receiving conversation updates and changing user information.
Now everything in the Github samples works for Skype For Business Online.