Is managed identity available to create IoT Hub client to avoid Azure Active Directory app and secret - azure-iot-hub

I am using below nuget package <PackageReference Include="Microsoft.Azure.Management.IotHub" Version="4.2.0" /> and trying to create IotHubClient.
I have registered one application with AAD and giving permission with IoT Hub instance and using below code to generate the IoT Hub client,
private async Task<IotHubClient> GetIotHubClient()
{
var authContext = new AuthenticationContext("https://login.microsoftonline.com/XXXXXXXXXXXX");
var credential = new ClientCredential(Configuration["AAD-APP-Client-ID", "AAD-APP-Client-Secret"));
var token = await authContext.AcquireTokenAsync("https://management.core.windows.net/", credential);
if (token == null) return null!;
var credentials = new TokenCredentials(token.AccessToken);
var client = new IotHubClient(credentials)
{
SubscriptionId = "my-SubscriptionId"
};
return client;
}
It's works and I am able to create IoT hub client to talk with it.
Question is, is this the only way to prepare IoTHub client, can some means of managed identity available so that I don't need to main AAD app and their secret's ?

Related

Google API - Authentication setup and .NET client

I'm trying to achieve two things from my C# client application using Google API.
List all users of my google directory
Get metadata of all emails for each user
It appears, however, that my service account configuration is giving me issues. This is what I have done.
Created project in console.cloud.google.com
Enabled Admin SDK and Gmail API from API's and Services
Created Service Account with Domain-Wide delegation and obtained credentials.json file.
4. On admin.google.com I went to Security / API Controls and manage Domain-wide delegation. From here I added new API Client from my Service Account client id and assigned the following scopes:
https://www.googleapis.com/auth/gmail.settings.basic
https://www.googleapis.com/auth/gmail.settings.sharing
https://www.googleapis.com/auth/admin.directory.user.readonly
Finally, when I want to try to retrieve users list I get error: Expected OAuth 2 access token, login cookie or other valid authentication credential
static void Main(string[] args)
{
using (var stream =
new FileStream("..\\..\\..\\credentials.json", FileMode.Open, FileAccess.Read))
{
var credential = GoogleCredential.FromFile("..\\..\\..\\credentials.json");
var dirservice = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "testbuildingnomiproductname",
});
var listReq = dirservice.Users.List();
Users allUsers = listReq.Execute();
int counter = 0;
foreach (User myUser in allUsers.UsersValue)
{
Console.WriteLine("*" + myUser.PrimaryEmail);
counter++;
}
Console.WriteLine(counter);
Console.ReadKey();
}
}

Call Azure API from WebJob/ Shared code between WebJob and web api

I have a web api in an ASE and an associated web job. I am trying to call this web api from the web job but it always fails with winhttpexception: a security error has occurred. I have put in all the tls related settings but still getting the error.
Any suggestions on the error?
Also is there a way to share code between WebJob and web api?
I was able to resolve the issue by setting the below in my code.This resolved the Security Error.
using(var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (sender,certificate,chain,sslPolicyErrors) => true
})
You could create a console app and publish it as Azure WebJobs. For username and password you could click Get Publish Profile in your Azure webapp overview to get them.
Then you could use the following code in Console App to call your Azure Webapi.
string userName = "$xxxxxx";
string userPassword = "xxxxxxxxxxxxx";
string webAppName = "xxxxxx";
var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{userName}:{userPassword}"));
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Basic " + base64Auth);
var baseUrl = new Uri($"https://{webAppName}.azurewebsites.net/api/values");
var result = client.GetAsync(baseUrl).Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsStringAsync();
readTask.Wait();
var value = readTask.Result;
Console.WriteLine(value.ToString());
}
}
Console.WriteLine("run successfully");
Output as below:

How to use the same authorization pipeline for WebAPI with SignalR

I am adding signalr functionality to a website that only logged in users will have access to for communicating with each other. I also would like to use the same pipeline to allow azure worker roles to communicate with a user indicating job statuses for long running queue-based processes, running on their behalf. I found an example here at this url that outlines how to use the OAuth Bearer tokens with signalr: http://blog.marcinbudny.com/search?q=Authentication+signalr+OAuth+#.V5KBaY52xTM. The problem is that his example seems to turn off the OAuthBearerTokens which I am using in my code for web api authentication and authorization. Here is the code from the article:
//app.UseCookieAuthentication(new CookieAuthenticationOptions());
//app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
//app.UseOAuthBearerTokens(OAuthOptions);
app.UseOAuthAuthorizationServer(OAuthOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
Provider = new ApplicationOAuthBearerAuthenticationProvider(),
});
and this is my code utilizing the technique in this article:
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
PublicClientId = "self";
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId, UserFactory),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(2),
AllowInsecureHttp = false
};
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
map.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
{
Provider = new QueryStringOAuthBearerAuthenticationProvider()
});
var hubConfiguration = new HubConfiguration
{
Resolver = GlobalHost.DependencyResolver,
};
map.RunSignalR(hubConfiguration);
});
How can I allow signalr to access the user's information in the same way I would for web api when there are times I will need worker role processes to pass information to clients as well as client-side code does?

Office365 authentication without login redirection

I'm trying to load data from Office365 email without need for user interaction. I've created Azure App and I have Client ID and Client secret.
I also have user information (email + password).
I need to call Office365 API to download emails from mailbox. But I need application to download them in background without user interaction (redirecting to MS/Office365 login page) to get authenticated/logged into mailbox.
Is there any way how to do this only through Office API, without need of redirection?
Thanks for any info.
Yes, you are able to create a daemon service app using the Client Credential flow to authenticate the app.
Here is a code sample to retrieve the mails using Microsoft Graph SDK with this flow:
string clientId = "";
string clientsecret = "";
string tenant = "";
string resourceURL = "https://graph.microsoft.com";
string authority = "https://login.microsoftonline.com/" + tenant + "/oauth2/token";
string userMail = "user1#yourdomain.onmicrosoft.com";
var credential = new ClientCredential(clientId, clientsecret);
AuthenticationContext authContext =new AuthenticationContext(authority);
var authResult = await authContext.AcquireTokenAsync(resourceURL, credential);
var graphserviceClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
(requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authResult.AccessToken);
return Task.FromResult(0);
}));
var items = await graphserviceClient.Users[userMail].Messages.Request().OrderBy("receivedDateTime desc").GetAsync();
foreach (var item in items)
{
Console.WriteLine(item.Subject);
}
And we need to register the app on the Azure AD portal and grant the app Mail.Read scope like figure below:
Refer to here for more detail about calling Microsoft Graph in a service or daemon app

How to delegate Facebook SecurityToken to WCF service

I have the following components:
WPF Application,
Identity Server,
WCF Web Service,
WPF Application uses WebBrowser control to authenticate using Thintecture Identity Server using WS-Federation. Identity Server has enabled Home Realm Discovery and allow authentication using Facebook, Live ID and Google. After authentication I get ReqquestSecurityTokenResponse message, which I convert into SecurityToken.
After getting this SecurityToken I want to call WebService. I think I need create ActAsToken issued again by Thintecture Identity Server, but I can't configure it.
var serviceAddress = "http://localhost:7397/Service1.svc";
var token3 = token2.ToSecurityToken();
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.Message);
binding.Security.Message.IssuedKeyType = System.IdentityModel.Tokens.SecurityKeyType.SymmetricKey;
binding.Security.Message.IssuerAddress = new EndpointAddress("https://dev3.example.com/Identity/issue/wsfed");
binding.Security.Message.IssuerBinding = new WS2007HttpBinding();
var factory = new ChannelFactory<IService1Channel>(binding,
new EndpointAddress(
new Uri(serviceAddress),
new DnsEndpointIdentity("dev3.example.com")));
factory.Credentials.SupportInteractive = false;
var proxy = factory.CreateChannelWithActAsToken(token3);
{
try
{
var output = proxy.GetData(1);
MessageBox.Show(output);
proxy.Dispose();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
But I get exceptions.
WebService is configured using Identity and access... VS extension.
Is this scenario possible?
you don't need an ActAs - you can use the CreateChannelWithIssuedToken method to create your WCF proxy.
You also need to configure bearer keys on the WCF service and client (instead of SymmetricKey).