Azure AD Authentication with Salesforce - c#

We are getting an error while authenticating Azure AD with Salesforce
'The user or administrator has not consented to use the application
with ID '1d75cc30-c553-4733-9a88-501e1b45821a' named 'Salesforce'.
Send an interactive authorization request for this user and resource'
.
We have Created an app in Azure directory and also granted all the required permissions to the app.
We are using HTTP request to get the authentication token.
List<String> urlParams = new List<String> {
'grant_type=authorization_code',
'code=' + EncodingUtil.urlEncode(code, 'UTF-8'),
'client_id=' + EncodingUtil.urlEncode(client_id, 'UTF-8'),
'client_secret=' + EncodingUtil.urlEncode(client_secret, 'UTF-8'),
'redirect_uri=' + EncodingUtil.urlEncode(redirect_uri, 'UTF-8'),
'resource=' + EncodingUtil.urlEncode('https://outlook.office365.com', 'UTF-8')
};
String body = String.join(urlParams, '&');
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint(access_token_url);
req.setMethod('POST');
//req.setHeader('Content-Type', 'application/json');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setHeader('Accept', 'application/json');
req.setBody(body);
HttpResponse res = h.send(req);
Please suggest what could be wrong here.

Related

DocuSign API and DocumentPDFs docPDFs = apiService.RequestDocumentPDFs(envelopeID);

I am using the code below to connect to DocuSign API.
WHAT AM I doing wrong, I keep getting Username and Password not correct when they are!
String auth = "<DocuSignCredentials><Username>john.connolly#lechase.com</Username><Password>password</Password><IntegratorKey>20be051c-4c25-46c1-b0f1-1f10575a2e40</IntegratorKey></DocuSignCredentials>";
DSAPIServiceSoapClient client = new DSAPIServiceSoapClient("DSAPIServiceSoap");
using (System.ServiceModel.OperationContextScope scope = new System.ServiceModel.OperationContextScope(client.InnerChannel))
{
System.ServiceModel.Channels.HttpRequestMessageProperty 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 status = client.RequestStatusEx("12d46951-1f1c-48cd-9a28-e51685d67ccd");
Console.Out.WriteLine("Subject: " + status.Subject);
}
Since you use the (Legacy Header Authentication uses the X-DocuSign-Authentication header):
Use the Authentication: login method
to retrieve the account number and the baseUrl for the account.
The url for the login method is www.docusign.net for production and
demo.docusign.net for the developer sandbox. The baseUrl field is
part of the loginAccount object. See the docs and the loginAccount
object
The baseUrl for the selected account, in production, will start with na1, na2, na3, eu1, or something else. Use the baseUrl that is
returned to create the basePath (see the next step.) Use the
basePath for all of your subsequent API calls.
As returned by login method, the baseUrl includes the API version and account id. Split the string to obtain the basePath, just the
server name and api name. Eg, you will receive
https://na1.docusign.net/restapi/v2/accounts/123123123. You want
just https://na1.docusign.net/restapi
Instantiate the SDK using the basePath. Eg ApiClient apiClient = new ApiClient(basePath);
Set the authentication header as shown in the examples by using Configuration.Default.AddDefaultHeader Ref.
Sample Code: Try a verbatim string for your auth string.
string auth = #"<DocuSignCredentials>
<Username>john.connolly#lechase.com</Username>
<Password>S3cre+p455w0Rd</Password>
<IntegratorKey>20be051c-4c25-46c1-b0f1-1f10575a2e40</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;
}

Unable to Create User using Google Admin SDK - Exception 401 Unauthorized

I am trying to populate users in my C# application. However, I keep getting this exception:
{"Error occurred while sending a direct message or getting the response."}
[DotNetOpenAuth.Messaging.ProtocolException]: {"Error occurred while sending a direct message or getting the response."}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
InnerException: {"The remote server returned an error: (401) Unauthorized."}
Message: "Error occurred while sending a direct message or getting the response."
Source: "Google.Apis"
StackTrace: " at Google.Apis.Requests.ClientServiceRequest`1.Execute() in c:\\code.google.com\\google-api-dotnet-client\\default\\Tools\\BuildRelease\\bin\\Release\\release140\\default\\Src\\GoogleApis\\Apis\\Requests\\ClientServiceRequest.cs:line 88\r\n at GoogleAccountsPopulation.DirectoryServiceClient.CreateUser(User user) in E:\\GoogleAccountsPopulation\\GoogleAccountsPopulation\\GoogleAccountsPopulation\\DirectoryServiceClient.cs:line 70\r\n at GoogleAccountsPopulation.frmGoogleAccountsPopulation.btnPopulateAccounts_Click(Object sender, EventArgs e) in E:\\GoogleAccountsPopulation\\GoogleAccountsPopulation\\GoogleAccountsPopulation\\PopulateForm.cs:line 449"
TargetSite: {TResponse Execute()}
The exception is being raised on the line:
userServiceClient.CreateUser(user);
Here is the codes for the service:
DirectoryServiceSpecs userServiceSpecs = new DirectoryServiceSpecs()
{
CertificateFilePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\Certificates\\" + gappsSchool.CertificateFile,
PrivateKey = gappsSchool.PrivateKey,
ServiceAccountId = gappsSchool.ServiceAccountId,
ServiceAccountUser = gappsSchool.ServiceAccountUser,
Domain = gappsSchool.EmailDomain,
ServiceScope = DirectoryService.Scopes.AdminDirectoryUser.GetStringValue()
};
DirectoryServiceClient userServiceClient = new DirectoryServiceClient(userServiceSpecs);
User user = new User();
user.Name = new UserName();
if (userNames.Length > 1)
{
user.Name.FamilyName = lmsUser.Name.Replace(userNames[0], "").Trim();
user.Name.GivenName = userNames[0];
}
else
{
user.Name.FamilyName = "N.A.";
user.Name.GivenName = userNames[0];
}
user.Name.FullName = lmsUser.Name;
user.Password = lmsUser.Password;
user.PrimaryEmail = lmsUser.EmailAccount + "#" + gappsSchool.EmailDomain;
if (Properties.Settings.Default.LMSPasswardHashAlgorithm.Trim() != string.Empty)
user.HashFunction = "MD5";
user = userServiceClient.CreateUser(user);
trackEntries.Add(new TrackEntry()
{
EmailAccount = lmsUser.EmailAccount,
SchoolName = gappsSchool.Name,
Status = "Success",
Error = ""
});
log.Info("Successfully created user \"" + lmsUser.EmailAccount + "\" (" + lmsUser.Id.ToString() + ", " + gappsSchool.Name + ").");
userServiceClient.CreateUser(user);
Authorization
In Google Apps domains, the domain administrator can grant third-party applications with domain-wide access to its users' data — this is referred as domain-wide delegation of authority. To delegate authority this way, domain administrators can use service accounts with OAuth 2.0.
Here is the list of scopes available in Directory API.
To request access using OAuth 2.0, your application needs the scope information, as well as information that Google supplies when you register your application (such as the client ID and the client secret).
Try checking how you perform Google Apps Domain-Wide delegation of authority. You are receiving an Exception 401 Unauthorized maybe because your service account is not authorized to create a user (wrong scope used or the scope to used is not added), based from Emily's answer - you must impersonate a
administrator account (Note: only administrator can create users).

picasaweb.google.com OAuth 2.0

We have a problem with the new authentication PicasaWeb
We are using this code in C # .NET 2012 ( Framework 4.5.1 )
const string ServiceAccountEmail = "xxxxxxxxxxxxxxxxxxxx#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"C:\key.p12", "notasecret", X509KeyStorageFlags.Exportable);
var serviceAccountCredentialInitializer =
new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
Scopes = new[] { "https://picasaweb.google.com/data/"}
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Result)
throw new InvalidOperationException("Access token request failed.");
var requestFactory = new GDataRequestFactory(null);
requestFactory.CustomHeaders.Add("Authorization: Bearer " + credential.Token.AccessToken);
requestFactory.CustomHeaders.Add("Gdata-version: 2");
PicasaService service = new PicasaService("api-project");
service.RequestFactory = requestFactory;
PhotoQuery query = new PhotoQuery(PicasaQuery.CreatePicasaUri(_IdUsuari, _albumid));
PicasaFeed feed = service.Query(query);
We have an error to retrieve the PicasaFeed :
Unhandled Exception: Google.GData.Client.GDataRequestException: Execution of aut hentication request returned unexpected result: 404
We've done every step of the link : Google.GData.Client.GDataRequestException - Authentication suddenly fails in old code
But it has not worked , is that we are using 4.5.1 and not 4.5 ?
We have done some testing generating the token from the page of Google : https://developers.google.com/oauthplayground
We selected Picasa Web API v2 with the scope: https://picasaweb.google.com/data/
This has generated a token. We have marked the "Auto -refresh the token before it expires" option as it expires in 3600 seconds .
The question is whether this token changes after 3600 seconds? .
With the token generated from this link we have replaced the previous code , where " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " is the token generated :
var requestFactory = new GDataRequestFactory(null);
requestFactory.CustomHeaders.Add("Authorization: Bearer " + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
requestFactory.CustomHeaders.Add("Gdata-version: 2");
PicasaService service = new PicasaService("api-project");
service.RequestFactory = requestFactory;
PhotoQuery query = new PhotoQuery(PicasaQuery.CreatePicasaUri(_IdUsuari, _albumid));
PicasaFeed feed = service.Query(query);
And with this token if it works.
Any thoughts that the first code generated by the token code is not working properly for generating tokens and readings to Picasa.
Does anyone have any solution?
Thank you very much
I only wanted to add, that I have the same problem since May, 25.
Since then the api worked correctly and afterwords I get the 404 (page not found error) too.
Maybe google has changed something.
Because my code look similar! and I don't see any error in your code.
Greetings
Mike

Using EWS Managed Api with Office 365 Api

I am trying to use EWS managed Api with Office 365 Api via Azure AD. I have done the following tasks so far.
I have the admin privilege in Azure AD.
I have successfully registered my application in Azure AD.
I got Client ID, App key and resource ID from Azure AD.
I have enabled "Have full access to user's mailbox. as suggested by Jason.
I have successfully created a MVC5 web application.
I have followed this blog post of Jeremy.
Here the link of the blog I have followed :
http://www.jeremythake.com/2014/08/using-the-exchange-online-ews-api-with-office-365-api-via-azure-ad/#comment-280653
Code in my controller:
var outlookClient = await AuthHelper.EnsureOutlookServicesClientCreatedAsync("Mail");
IPagedCollection<IMessage> messagesResults = await outlookClient.Me.Messages.ExecuteAsync();
string messageId = messagesResults.CurrentPage[0].Id;
string tokenx = AuthHelper.GetSessionToken();
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
service.HttpHeaders.Add("Authorization", "Bearer " + tokenx);
service.PreAuthenticate = true;
service.SendClientLatencies = true;
service.EnableScpLookup = false;
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ExFolder rootfolder = ExFolder.Bind(service, WellKnownFolderName.MsgFolderRoot);
Edited : I am getting accessToken Successfully and using it to make call against EWS managed Api, but it fails with 403:Forbidden exception. Your help will be highly appreciated.
best regards,
Jason Johnston helped me solve my problem.
The link:
Office 365 / EWS Authentication using OAuth: The audience claim value is invalid
I checked the EWS trace, I learned that EWS was complaining about invalid token and insufficient privileges. I re-registered my application to Azure AD and enabled full access to mailbox.
I commented this below code.
//var outlookClient = await AuthHelper.EnsureOutlookServicesClientCreatedAsync("Mail");
//try
//{
// IPagedCollection<IMessage> messagesResults = await outlookClient.Me.Messages.ExecuteAsync();
// string messageId = messagesResults.CurrentPage[0].Id;
//}
//catch
//{
// System.Diagnostics.Debug.WriteLine("Something bad happened. !!");
//}
I am getting access token from this below link sample.
https://github.com/OfficeDev/Office-365-APIs-Starter-Project-for-ASPNETMVC
Here is the complete code of controller which does the main task of authentication.
string resourceUri = "https://outlook.office365.com";
var signInUserId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
var userObjectId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
AuthenticationContext authContext = new AuthenticationContext(Settings.Authority, new NaiveSessionCache(signInUserId));
string tokenx = await AuthHelper.AcquireTokenAsync(authContext, resourceUri, Settings.ClientId, new UserIdentifier(userObjectId,UserIdentifierType.UniqueId));
System.Diagnostics.Debug.WriteLine("Token:" + tokenx);
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
service.TraceListener = new EwsTrace();
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.HttpHeaders.Add("Authorization", "Bearer " + tokenx);
service.PreAuthenticate = true;
service.SendClientLatencies = true;
service.EnableScpLookup = false;
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ExFolder rootfolder = ExFolder.Bind(service, WellKnownFolderName.MsgFolderRoot);
Console.WriteLine("The " + rootfolder.DisplayName + " has " + rootfolder.ChildFolderCount + " child folders.");
The important thing I noticed is I can't use the same token to access office365 api and EWS managed Api as EWS works with full mailbox access while office365 doesn't. I request the developer to confirm this,maybe I am doing something wrong, however my problem is solved for now.
Yep, that's right. The scope required for EWS isn't compatible with the Office 365 APIs, and vice versa.

Twitterizer 2.2 Sending help

Hi I am working on sending twitter updates from my asp.net website. I have the authorization down but I am stuck when it gets to sending the tweet here is my code behind:
protected void btnAuth_Click(object sender, EventArgs e)
{
// add these to web.config or your preferred location
var consumerKey = ConfigurationManager.AppSettings["consumerKey"];
var consumerSecret = ConfigurationManager.AppSettings["consumerSecret"];
//If User is not valid user
if (Request.QueryString["oauth_token"] == null)
{
//Step 1: Get Request Token
OAuthTokenResponse RequestToken = OAuthUtility.GetRequestToken(consumerKey,consumerSecret);
//Step 2: Redirect User to Requested Token
Response.Redirect("http://twitter.com/oauth/authorize?oauth_token="+ RequestToken.Token);
}
else
{
//For Valid User
string Oauth_Token = Request.QueryString["oauth_token"].ToString();
var accessToken = OAuthUtility.GetAccessToken(consumerKey, consumerSecret, Oauth_Token, txtPIN.Text.Trim());
lblMessage.Text = "<b>Hello " + accessToken.ScreenName + ", Welcome to my Twitter App<b>";
lblMessage.Text += "<br/> Token: " + accessToken.Token;
lblMessage.Text += "<br/> TokenSecret: " + accessToken.TokenSecret;
lblMessage.Text += "<br/> UserId: " + accessToken.UserId;
lblMessage.Text += "<br/> VerificationString: " + accessToken.VerificationString;
}
}
protected void btnTweet_Click(object sender, EventArgs e)
{
// add these to web.config or your preferred location
var consumerKey = ConfigurationManager.AppSettings["consumerKey"];
var consumerSecret = ConfigurationManager.AppSettings["consumerSecret"];
OAuthTokens accessToken = new OAuthTokens();
accessToken.AccessToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
accessToken.AccessTokenSecret = "xxxxxxxxxxxxxxxxxxxx";
accessToken.ConsumerKey = consumerKey;
accessToken.ConsumerSecret = consumerSecret;
TwitterStatus TweetStatus = new TwitterStatus();
TweetStatus.Update(accessTokens, txtTweet.Text);
}
I dont know how to get the AccessToken & AccessTokenSecret. Any help would be great thanks.
The access token and secret values are returned to your application from Twitter when you call the OAuthUtility.GetAccessToken method:
var accessToken = OAuthUtility.GetAccessToken(consumerKey, consumerSecret, Oauth_Token, Request.QueryString["oauth_verifier"]);
The one-time authorization process goes as follows:
1) Get a request token
2) Send the user to Twitter to login and grant access
3) Receive the user at the callback url, collect the oauth_token and oauth_verifier values from the querystring
4) Exchange the request token and verifier for the access token
After you have the access token, you should store it so that the user isn't required to go through the process again (the access token does not expire).
I noticed that you're collecting a PIN value from the user, but it appears as though your application is a website. The web flow (not pin-based authentication) will provide a much more pleasant user experience.
If you have more questions, please post them to the Twitterizer forums, http://forums.twitterizer.net.
After a successful login, you just have to set all four variables in your OAuthTokens (AccessToken & AccessTokenSecret are both return on successful OAuthUtility.GetAccessToken)
I suggest you store you AccessToken and AccessToken in a Cookie once Authenticated.
Create a Static Class where you can return all four tokens and do a check if all four values are supplied ELSE logged-out.

Categories