I'm trying to create an Authentication function for user login, but my idea is to expose the "function keys" of the rest of the functions. So the mobile app can grave the keys to star calling the rest of the functions.
Is a way to do this?
If you want to manage Azure function key, you can use the Key management API to implement it. For more details, please refer to document
Get function key
GET https://<functionappname>.azurewebsites.net/admin/functions/{functionname}/keys
Create Function key
PUT https://<functionappname>.azurewebsites.net/admin/functions/{functionname}/keys/{keyname}
{
"name": "keyname",
"value" : "keyvalue"
}
The code
tring clientId = "client id";
string secret = "secret key";
string tenant = "tenant id";
var functionName ="functionName";
var webFunctionAppName = "functionApp name";
string resourceGroup = "resource group name";
var credentials = new AzureCredentials(new ServicePrincipalLoginInformation { ClientId = clientId, ClientSecret = secret}, tenant, AzureEnvironment.AzureGlobalCloud);
var azure = Azure
.Configure()
.Authenticate(credentials)
.WithDefaultSubscription();
var webFunctionApp = azure.AppServices.FunctionApps.GetByResourceGroup(resourceGroup, webFunctionAppName);
var ftpUsername = webFunctionApp.GetPublishingProfile().FtpUsername;
var username = ftpUsername.Split('\\').ToList()[1];
var password = webFunctionApp.GetPublishingProfile().FtpPassword;
var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}"));
var apiUrl = new Uri($"https://{webFunctionAppName}.scm.azurewebsites.net/api");
var siteUrl = new Uri($"https://{webFunctionAppName}.azurewebsites.net");
string JWT;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", $"Basic {base64Auth}");
var result = client.GetAsync($"{apiUrl}/functions/admin/token").Result;
JWT = result.Content.ReadAsStringAsync().Result.Trim('"'); //get JWT for call funtion key
}
// get key
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + JWT);
var key = await client.GetAsync($"{siteUrl}/admin/functions/{functionName}/keys").Result.Content.ReadAsStringAsync();
}
// create key
var map = new Dictionary<string, string>();
map.Add("name", "keyName");
map.Add("value", "keyVaule");
using (var client = new HttpClient()) {
var content = new StringContent(JsonConvert.SerializeObject(map), System.Text.Encoding.UTF8, "application/json");
await client.PutAsync($"{siteUrl}/admin/functions/{functionname}/keys/{keyname}", content);
}
Besides, according to my research, we also can use Azure REST API to manage Azure function key. For more details, please refer to
a. Create Azure function key
b. List Azure function key
Related
We were using AmazonS3EncryptionClient in our code to interact with S3 bucket using client side encryption. But on updating nuget package today, I noticed that AmazonS3EncryptionClient has been marked obsolete. Looks like we will need to use AmazonS3EncryptionClientV2 if we want to get continuous update going forward. I am having this issue while trying to migrate from AmazonS3EncryptionClient to AmazonS3EncryptionClientV2.
In our old code we were using AmazonS3EncryptionClient constructor that takes RegionEnpoint as a parameter. see image below. Looks like constructors that takes RegionEnpoint has been removed in AmazonS3EncryptionClientV2.
Old code that was working to GetObject from S3 bucket.
S3BucketConfiguration _s3BucketConfiguration = provider
.GetService<IOptionsSnapshot<S3BucketConfiguration>>()
.Value;
var credential = new BasicAWSCredentials(
_s3BucketConfiguration.AccessKey, _s3BucketConfiguration.SecurityKey);
RegionEndpoint bucketRegion =
RegionEndpoint.GetBySystemName(_s3BucketConfiguration.Region);
EncryptionMaterials encryptionMaterials = new EncryptionMaterials(_s3BucketConfiguration.KMSKeyId);
var client = new AmazonS3EncryptionClient(credential, bucketRegion, encryptionMaterials);
GetObjectResponse response = await _client.GetObjectAsync(new GetObjectRequest
{
BucketName = _s3BucketConfig.BucketName,
Key = filePath
});
I cannot pass in RegionEnpoint in AmazonS3EncryptionClientV2.
My Code so far.
S3BucketConfiguration _s3BucketConfiguration = provider
.GetService<IOptionsSnapshot<S3BucketConfiguration>>()
.Value;
var credential = new BasicAWSCredentials(
_s3BucketConfiguration.AccessKey, _s3BucketConfiguration.SecurityKey);
RegionEndpoint bucketRegion =
RegionEndpoint.GetBySystemName(_s3BucketConfiguration.Region);
var encryptionMaterials = new EncryptionMaterialsV2(
_s3BucketConfiguration.KMSKeyId,
KmsType.KmsContext,
new Dictionary<string, string>()
);
var config = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy);
//If I add this line it will instantiate AmazonS3EncryptionClientV2 but, the GetObject call fails.
//If I do not add this line, it will give me same error while instiantiating AmazonS3EncryptionClientV2
//config.RegionEndpoint = bucketRegion;
vr client = new AmazonS3EncryptionClientV2(credential, config, encryptionMaterials);
GetObjectResponse response = client.GetObjectAsync(new GetObjectRequest
{
BucketName = _s3BucketConfig.BucketName,
Key = filePath,
}).GetAwaiter().GetResult();
Exception
No RegionEndpoint or ServiceURL configured
I can successfully encrypt with V1 and decrypt with V2 client along with passing the RegionEndpoint.
var configuration = new AmazonS3CryptoConfiguration()
{
RegionEndpoint = RegionEndpoint.USWest2
};
var material = new EncryptionMaterials(KmsKeyId);
var client = new AmazonS3EncryptionClient(configuration, material);
var putObjectResponse = await client.PutObjectAsync(new PutObjectRequest()
{
ContentBody = ContentBody,
BucketName = Bucket,
Key = Key
});
if (putObjectResponse.HttpStatusCode == System.Net.HttpStatusCode.OK)
{
var configurationV2 = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy)
{
RegionEndpoint = RegionEndpoint.USWest2
};
var materialV2 = new EncryptionMaterialsV2(KmsKeyId, KmsType.KmsContext, new Dictionary<string, string>());
var clientV2 = new AmazonS3EncryptionClientV2(configurationV2, materialV2);
var getObjectResponse = await clientV2.GetObjectAsync(new GetObjectRequest()
{
BucketName = Bucket,
Key = Key
});
using (var reader = new StreamReader(getObjectResponse.ResponseStream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
Can you make sure you are using the same RegionEndpoint during the encryption and decryption?
I need to read the gmail inbox feed using Oauth2.0. Simulating in the postman,
Auth URL : https://accounts.google.com/o/oauth2/auth
Access Token URL : https://accounts.google.com/o/oauth2/token
Client ID : XXXXX.apps.googleusercontent.com
Client Secret : XXXXX
Scope : https://mail.google.com/mail/feed/atom
GrantType: Authorization Code
I requested the token and used it on the header
Authorization - Bearer XXXXXXXXXX.
And I made the request via GET right in my scope and got my email feeds. Works!!!
The postman generates a code in C #, but the token expires.
var client = new RestClient("https://mail.google.com/mail/feed/atom/");
var request = new RestRequest(Method.GET);
request.AddHeader("postman-token", "d48cac24-bd3e-07b5-c616-XXXXXXXX");
request.AddHeader("cache-control", "no-cache");
request.AddHeader("authorization", "Bearer ya29.a0AfH6SMDZlUmw0xLHAoYIJuIfTkXXXXXXXXQSPP17GmXT26fJEfWB9w8UiwQ2YF32-nOp6zY9H_lwJEEXXXXXXXXXXXYK4e0tcZkieGbBl5Eow2M-7Gxp20kfDtXXXXXVjiXymLXyMkYEI");
IRestResponse response = client.Execute(request);
I'm trying to do it via Google.Api, using GoogleAuthorizationCodeFlow and already using token refresh.
With the code below, I got authorization from the application, but I can't read the xml atom feed
GoogleAuthorizationCodeFlow flow;
var assembly = Assembly.GetExecutingAssembly();
var clientfile = #"client_secrets.json";
using (var stream = new FileStream(clientfile, FileMode.Open, FileAccess.Read))
{
flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
DataStore = new FileDataStore("StoreTest"),
ClientSecretsStream = stream,
Scopes = new[] { "https://mail.google.com/mail/feed/atom/" }
});
}
var uri = Request.Url.ToString();
var code = Request["code"];
if (code != null)
{
var token = flow.ExchangeCodeForTokenAsync(UserId, code,
uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result;
// Extract the right state.
var oauthState = AuthWebUtility.ExtracRedirectFromState(
flow.DataStore, UserId, Request["state"]).Result;
Response.Redirect(oauthState);
}
else
{
var result = new AuthorizationCodeWebApp(flow, uri, uri).AuthorizeAsync(UserId,
CancellationToken.None).Result;
if (result.RedirectUri != null)
{
// Redirect the user to the authorization server.
Response.Redirect(result.RedirectUri);
}
else
{
// The data store contains the user credential, so the user has been already authenticated.
var gmailfeed = new GmailService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "GetFeed",
});
var inboxlistRequest = gmailfeed.Users.Messages.List("me");
inboxlistRequest.LabelIds = "Label_19780355190759038";
inboxlistRequest.IncludeSpamTrash = false;
var emailListResponse = inboxlistRequest.Execute();
foreach (var mail in emailListResponse.Messages)
{
var mailId = mail.Id;
var threadId = mail.ThreadId;
Message message = gmailfeed.Users.Messages.Get("me", mailId).Execute();
Console.WriteLine((message.Snippet));
}
}
}
I got to read the email, but I need the xml atom feed.
Could someone help me how I make this call to get the atom feed, using the granted token. If there is an easier way to do it too, it would be cool to share.
Thank you
Resolved using respsharp, restclient!!
tks
How can I get ID Token from custom token?
[Fact]
public void Get_ID_Token_For_Service_Account_Test()
{
using (Stream stream = new FileStream(ServiceAccountJsonKeyFilePath, FileMode.Open, FileAccess.Read))
{
ServiceAccountCredential credential = ServiceAccountCredential.FromServiceAccountData(stream);
FirebaseApp.Create(new AppOptions
{
Credential = GoogleCredential.FromServiceAccountCredential(credential),
ServiceAccountId = ServiceAccountId,
});
var uid = "Some UID";
var additionalClaims = new Dictionary<string, object>
{
{"dmitry", "pavlov"}
};
string customToken = FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid, additionalClaims).Result;
string idToken= null; // How to get this?
FirebaseToken token = FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken, CancellationToken.None).Result;
Assert.NotNull(token);
Assert.True(token.Claims.ContainsKey("dmitry"));
}
}
I see samples for some other languages/platforms but not for C# - how to get ID token via current user here - Retrieve ID tokens on clients. But for C# neither UserRecord nor FirebaseAuth provides ID Token. Any pointers are much appreciated.
I have found the way to get the ID token in FirebaseAdmin integration tests - see method SignInWithCustomTokenAsync. The only thing I have to adjust was base URL: according to Firebase Auth REST API documentation it should be
https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken
The API KEY refers to the Web API Key, which can be obtained on the project settings page in your admin console.
So the adjusted code looks like this:
private static async Task<string> SignInWithCustomTokenAsync(string customToken)
{
string apiKey = "..."; // see above where to get it.
var rb = new Google.Apis.Requests.RequestBuilder
{
Method = Google.Apis.Http.HttpConsts.Post,
BaseUri = new Uri($"https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken")
};
rb.AddParameter(RequestParameterType.Query, "key", apiKey);
var request = rb.CreateRequest();
var jsonSerializer = Google.Apis.Json.NewtonsoftJsonSerializer.Instance;
var payload = jsonSerializer.Serialize(new SignInRequest
{
CustomToken = customToken,
ReturnSecureToken = true,
});
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
var parsed = jsonSerializer.Deserialize<SignInResponse>(json);
return parsed.IdToken;
}
}
I need to get the keys through code, not through a portal. For doing this I have found REST API in Google.
This is the link to Azure Key management API, but do this we need to do an authentication.
We have to develop all this using C# only.
Regarding the issue, please refer to the following code.
#install Microsoft.Azure.Management.ResourceManager.Fluent and Microsoft.Azure.Management.Fluent
string clientId = "client id";
string secret = "secret key";
string tenant = "tenant id";
var functionName ="functionName";
var webFunctionAppName = "functionApp name";
string resourceGroup = "resource group name";
var credentials = new AzureCredentials(new ServicePrincipalLoginInformation { ClientId = clientId, ClientSecret = secret}, tenant, AzureEnvironment.AzureGlobalCloud);
var azure = Azure
.Configure()
.Authenticate(credentials)
.WithDefaultSubscription();
var webFunctionApp = azure.AppServices.FunctionApps.GetByResourceGroup(resourceGroup, webFunctionAppName);
var ftpUsername = webFunctionApp.GetPublishingProfile().FtpUsername;
var username = ftpUsername.Split('\\').ToList()[1];
var password = webFunctionApp.GetPublishingProfile().FtpPassword;
var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{password}"));
var apiUrl = new Uri($"https://{webFunctionAppName}.scm.azurewebsites.net/api");
var siteUrl = new Uri($"https://{webFunctionAppName}.azurewebsites.net");
string JWT;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", $"Basic {base64Auth}");
var result = client.GetAsync($"{apiUrl}/functions/admin/token").Result;
JWT = result.Content.ReadAsStringAsync().Result.Trim('"'); //get JWT for call funtion key
}
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + JWT);
var key = client.GetAsync($"{siteUrl}/admin/functions/{functionName}/keys").Result.Content.ReadAsStringAsync().Result;
}
Besides, you also can refer to the document.
I want to use microsoft graph in web api which is using .net core 2.0, I want to authenticate user without login prompt.
Following is the code I have used, Please correct me if my method is wrong.
string clientId = "";
string clientsecret = "";
string tenant = "";
string resourceURL = "https://graph.microsoft.com";
string userMail = "testuser3#company.com";
public async Task<string> GetMyEmailUser()
{
try
{
var result = "";
string AzureADAuthority = "https://login.microsoftonline.com/companyname.com";
AuthenticationContext authenticationContext = new AuthenticationContext(AzureADAuthority, false);
var credential = new ClientCredential(clientId, clientsecret);
var authenticationResult = authenticationContext.AcquireTokenAsync(resourceURL, credential).Result;
var token = authenticationResult.AccessToken;
using (var confClient = new HttpClient())
{
var url = "https://graph.microsoft.com/v1.0";
confClient.BaseAddress = new Uri(url);
confClient.DefaultRequestHeaders.Accept.Clear();
confClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
confClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = confClient.GetAsync(url + "/me/mailFolders/inbox/messages?$filter=isRead eq false&$top=100").Result;
var jsonString = JObject.Parse(await response.Content.ReadAsStringAsync());
IUserMessagesCollectionPage myDetails = JsonConvert.DeserializeObject<IUserMessagesCollectionPage>(jsonString["value"].ToString());
}
I am new to microsoft graph and would really appreciate your help. Thanks.