I am trying to use MS Azure Speaker recognition API (java) as per https://westus.dev.cognitive.microsoft.com/docs/services/563309b6778daf02acc0a508/operations/5645c3271984551c84ec6797 . I am able to get a identificationProfileId. The error occues when I try to enroll. Here is how I am enrolling
- get a wav file of the enrollment audio
- convert to base64 (thru online service)
- attach the base64 it as content to the call for enrollment along with identificationProfileId. I am doubtful about the b64 part
I am getting "Invalid Audio Format: Not a WAVE file - no RIFF header"
I am aware that the service needs the audio in PCM encoding as per doc.
Can someone pls let me know how to convert a wav audio to the required format that can be passed to the enrollment REST endpoint.
public class azureApiTest
{
public static String getID()
{
HttpClient httpclient = HttpClients.createDefault();
String ret = null;
try
{
URIBuilder builder = new URIBuilder("https://westus.api.cognitive.microsoft.com/spid/v1.0/identificationProfiles");
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/json");
request.setHeader("Ocp-Apim-Subscription-Key", "fad541725xxxxxxx3362125790411");
// Request body
JsonObject locale = new JsonObject();
locale.addProperty("locale", "en-us");
StringEntity reqEntity = new StringEntity(locale.toString());
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
JsonParser parser = new JsonParser();
JsonObject o = parser.parse(EntityUtils.toString(entity)).getAsJsonObject();
ret = o.get("identificationProfileId").getAsString();
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
finally
{
return ret;
}
}
public static void main(String[] args)
{
HttpClient httpclient = HttpClients.createDefault();
try
{
String id = azureApiTest.getID();
System.out.println("ID created = "+id);
String enrollURL = "https://westus.api.cognitive.microsoft.com/spid/v1.0/identificationProfiles/" +id + "/enroll";
System.out.println("enrollURL = "+enrollURL);
URIBuilder builder = new URIBuilder(enrollURL);
builder.setParameter("shortAudio", "true");
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "multipart/form-data");
request.setHeader("Ocp-Apim-Subscription-Key", "fad5417xxxxxxx3362125790411");
// Request body
File voiceb64 = new File("/Users/premnair/Desktop/vp/voice1b64.txt");
String data = FileUtils.readFileToString(voiceb64, "utf-8");
StringEntity reqEntity = new StringEntity(data);
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println(EntityUtils.toString(entity));
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
If I pass the file like in the snippet below it works !
File file = new File("/Users/jdoe/Desktop/vp/v5.wav");
request.setEntity( new FileEntity(file, ContentType.APPLICATION_OCTET_STREAM) );
Don't use base 64, just raw byte array data will work.
Related
I am trying to get a file using the shared key. I already get a list of files and directories by the shared key, but when I request to receive a specific file, I encounter this problem.
Code to generate shared key:
using System;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Web;
namespace StorageRestApiAuth
{
internal static class AzureStorageAuthenticationHelper
{
internal static AuthenticationHeaderValue GetAuthorizationHeader(
string storageAccountName, string storageAccountKey, DateTime now,
HttpRequestMessage httpRequestMessage, string ifMatch = "", string md5 = "")
{
// This is the raw representation of the message signature.
HttpMethod method = httpRequestMessage.Method;
String MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n\n\n\n{2}\n\n\n\n{3}{4}",
method.ToString(),
(method == HttpMethod.Get || method == HttpMethod.Head) ? String.Empty
: httpRequestMessage.Content.Headers.ContentLength.ToString(),
ifMatch,
GetCanonicalizedHeaders(httpRequestMessage),
GetCanonicalizedResource(httpRequestMessage.RequestUri, storageAccountName),
md5);
byte[] SignatureBytes = Encoding.UTF8.GetBytes(MessageSignature);
HMACSHA256 SHA256 = new HMACSHA256(Convert.FromBase64String(storageAccountKey));
string signature = Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));
returned.
AuthenticationHeaderValue authHV = new AuthenticationHeaderValue("SharedKey",
storageAccountName + ":" + Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes)));
return authHV;
}
private static string GetCanonicalizedHeaders(HttpRequestMessage httpRequestMessage)
{
var headers = from kvp in httpRequestMessage.Headers
where kvp.Key.StartsWith("x-ms-", StringComparison.OrdinalIgnoreCase)
orderby kvp.Key
select new { Key = kvp.Key.ToLowerInvariant(), kvp.Value };
StringBuilder sb = new StringBuilder();
foreach (var kvp in headers)
{
StringBuilder headerBuilder = new StringBuilder(kvp.Key);
char separator = ':';
foreach (string headerValues in kvp.Value)
{
string trimmedValue = headerValues.TrimStart().Replace("\r\n", String.Empty);
headerBuilder.Append(separator).Append(trimmedValue);
separator = ',';
}
sb.Append(headerBuilder.ToString()).Append("\n");
}
return sb.ToString();
}
private static string GetCanonicalizedResource(Uri address, string storageAccountName)
{
StringBuilder sb = new StringBuilder("/").Append(storageAccountName).Append(address.AbsolutePath);
NameValueCollection values = HttpUtility.ParseQueryString(address.Query);
foreach (var item in values.AllKeys.OrderBy(k => k))
{
sb.Append('\n').Append(item).Append(':').Append(values[item]);
}
return sb.ToString().ToLower();
}
}
}
With this code I can get a list of directories and files, but I can’t get a specific file.
I'm use this url to request: https://myaccount.file.core.windows.net/myshare/mydirectorypath/myfile
Error sending request:
{
"Error": {
"Code": "AuthenticationFailed",
"Message": "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:4c9ca5be-301a-0045-29c9-f20135000000\nTime:2020-03-05T08:36:05.9908405Z",
"AuthenticationErrorDetail": "The MAC signature found in the HTTP request 'here is my key' is not the same as any computed signature. Server used following string to sign: 'GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Thu, 05 Mar 2020 08:36:05 GMT\nx-ms-version:2017-04-17\n/my storage account/my share/myfile.JPG'."
}
}
I test in my site with your code and it works well. With your AzureStorageAuthenticationHelper and here it the following code that I get file content.
static void Main(string[] args)
{
GetFileContentAsyncREST("youraccount", "yourkey", CancellationToken.None).GetAwaiter().GetResult();
Console.WriteLine("Press any key to continue.");
Console.ReadLine();
}
private static async Task GetFileContentAsyncREST(string storageAccountName, string storageAccountKey, CancellationToken cancellationToken)
{
string uri = "https://xxxxx.file.core.windows.net/helloworld/directory/helloworld.txt";
Byte[] requestPayload = null;
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri)
{
Content = (requestPayload == null) ? null : new ByteArrayContent(requestPayload) })
{
DateTime now = DateTime.UtcNow;
httpRequestMessage.Headers.Add("x-ms-date", now.ToString("R", CultureInfo.InvariantCulture));
httpRequestMessage.Headers.Add("x-ms-version", "2017-04-17");
httpRequestMessage.Headers.Authorization = AzureStorageAuthenticationHelper.GetAuthorizationHeader(
storageAccountName, storageAccountKey, now, httpRequestMessage);
using (HttpResponseMessage httpResponseMessage = await new HttpClient().SendAsync(httpRequestMessage, cancellationToken))
{
if (httpResponseMessage.StatusCode == HttpStatusCode.OK)
{
string content = await httpResponseMessage.Content.ReadAsStringAsync();
Console.Write(content);
}
}
}
}
}
For more details, you could refer to this storage rest api with auth sample.
I am using Azure Graph API to import users from Azure AD. In the azure portal I have added multiple Applications.
I am getting clientId, tenantId from protal and creating a secret key with one year expiry. Using these values I am creating an access_token and using that token connecting to AD.
Here is the code
public static String loginUrlPrefix = "https://login.windows.net/";
public static String loginUrlSufix = "/oauth2/token";
public static String importUrl = "https://management.core.windows.net/<subscription-id>/services/importexport/";
#SuppressWarnings("deprecation")
public static String getToken(String tenantId,String clientId,String encodedSecretKey) {
try {
String secretKey = EncryptionUtils.decryptAES(encodedSecretKey);
secretKey = URLEncoder.encode(secretKey);
String urltoConnect = loginUrlPrefix+tenantId+loginUrlSufix;
String payLoad = "resource=https%3A%2F%2Fmanagement.core.windows.net%2F&client_id="+clientId+"&grant_type=client_credentials&client_secret=" + secretKey;
URL url = new URL(urltoConnect);
URLConnection connection = null;
connection = url.openConnection();
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoOutput(true);
java.io.OutputStreamWriter wr = new java.io.OutputStreamWriter(connection.getOutputStream());
wr.write(payLoad);
wr.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String content;
String html = "";
while ((content = br.readLine()) != null) {
if (!content.equals("") && content.length() != 0)
html += content.trim();
}
return html;
} catch (Exception e) {
e.printStackTrace();
try {
throw e;
} catch (Exception e1) {
e1.printStackTrace();
}
}
return null;
}
#SuppressWarnings("deprecation")
public static Boolean testADConnection(String accessToken,String tenant) {
try {
URL url = new URL(String.format("https://graph.windows.net/%s/tenantDetails?api-version=2013-04-05", tenant,
accessToken));
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Set the appropriate header fields in the request header.
conn.setRequestProperty("api-version", "2013-04-05");
conn.setRequestProperty("Authorization","Bearer "+ accessToken);
conn.setRequestProperty("Accept", "application/json;odata=minimalmetadata");
String goodRespStr = HttpClientHelper.getResponseStringFromConn(conn, true);
System.out.println(goodRespStr);
int responseCode = conn.getResponseCode();
if(responseCode == 200){
return true;
}
else{
System.out.println(goodRespStr);
}
} catch (Exception e) {
e.printStackTrace();
try {
throw e;
} catch (Exception e1) {
e1.printStackTrace();
}
}
return false;
}
public static void main(String[] args){
String tokenJSON = getToken(tenantId,clientId,secretKey);
if(tokenJSON != null){
JSONObject j = (JSONObject) JSONValue.parse(tokenJSON);
String token = (String) j.get("access_token");
testADConnection(token,tenantId);
}
}
This works fine with the first application I added. But when I add a second application with the same configuration and permissions this is not working.
I am getting a 403 error
"odata.error": {
"code": "Authentication_MissingOrMalformed",
"message": {
"lang": "en",
"value": "Access Token missing or malformed."
},
"date": "2016-12-02T07:27:59", }
Tenant Id i am passing same for both the applications (copied from show diagnostics in help menu) client id I am copying whatever is generated in Azure and labelled as Application Id.Secret Key I am generating in Azure portal with 1 year validity.
I'm trying to post image as byte array.
I have converted image to byte as using following code now I want to post it to server.
WriteableBitmap btmMap = new WriteableBitmap(bi);
System.Windows.Media.Imaging.Extensions.SaveJpeg(btmMap, ms, 200, 200, 0, 100);
result = ms.ToArray();
How can I now perform the POST action?
I suggest MIME multipart as content type. It is the content type best suited for byte array, if you ask me. One way to implement this:
public static async Task<string> Upload(byte[] data, string fileName, string uri)
{
HttpClient client = new HttpClient();
HttpMultipartFormDataContent content = new HttpMultipartFormDataContent("Upload----" + DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture));
InMemoryRandomAccessStream contentStream = new InMemoryRandomAccessStream();
DataWriter dw = new DataWriter(contentStream);
dw.WriteBytes(data);
await dw.StoreAsync();
await dw.FlushAsync();
dw.DetachStream();
contentStream.Seek(0);
HttpStreamContent streamContent = new HttpStreamContent(contentStream);
content.Add(streamContent, "MIMEFile", fileName);
try
{
using (var message = await client.PostAsync(new Uri(uri), content))
{
if (message.StatusCode != HttpStatusCode.Ok)
{
return String.Format("ERROR ({0})",message.StatusCode);
}
var result = await message.Content.ReadAsStringAsync();
return result;
}
}
catch (Exception ex)
{
return String.Format("ERROR ({0})", ex.Message);
}
}
Try below code:
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
var imageForm = new ByteArrayContent(result, 0, result.Count());
imagenForm.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
form.Add(imagenForm, "image", "nameholder.jpg");
HttpResponseMessage response = await httpClient.PostAsync("URL_here", form);
response.EnsureSuccessStatusCode();
string result = response.Content.ReadAsStringAsync().Result;
httpClient.Dispose();
Hope this help's you to get idea about how to pass byte arry to POST into API call.
EDIT:
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
form.Add(new StringContent(UserID), "UserID");
var imageForm = new ByteArrayContent(result, 0, result.Count());
imagenForm.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
form.Add(imagenForm, "image", "nameholder.jpg");
HttpResponseMessage response = await httpClient.PostAsync("URL_here", form);
response.EnsureSuccessStatusCode();
string result = response.Content.ReadAsStringAsync().Result;
httpClient.Dispose();
Here is the code, but it prompts error:
The image o3lceiy3.ioa201305211013360129.vhd does not exist.
the subscriptionId and X509Certificate2 are valid
internal class Program
{
public static X509Certificate2 Certificate { get; set; }
private static void Main(string[] args)
{
const string subscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
//#"https://management.core.windows.net/<subscription-id>/services/hostedservices/<cloudservice-name>/deployments";
var url = string.Format("https://management.core.windows.net/{0}/services/hostedservices/{1}/deployments",
subscriptionId, "edoc2cloudtest");
var myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.Method = "POST";
myReq.Headers.Add("x-ms-version", "2012-03-01");
myReq.Proxy = null;
myReq.Timeout = 30000;
myReq.ContentType = "application/xml";
var postData = ReadConfig();
using (var reqStream = myReq.GetRequestStream())
{
var data = Encoding.UTF8.GetBytes(postData);
reqStream.Write(data, 0, data.Length);
reqStream.Flush();
}
Certificate = GetX509Certificate();
myReq.ClientCertificates.Add(Certificate);
try
{
var myRes = (HttpWebResponse) myReq.GetResponse();
}
catch (WebException exWeb)
{
// Parse the web response.
Stream responseStream = exWeb.Response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
XmlDocument xDocResp = new XmlDocument();
xDocResp.Load(reader);
HttpWebResponse responseStatus = (HttpWebResponse)exWeb.Response;
responseStream.Close();
reader.Close();
var result = NiceFormatXml(xDocResp);
Console.WriteLine(result);
}
}
private static string NiceFormatXml(XmlDocument xDoc)
{
StringBuilder niceString = new StringBuilder();
StringWriter strWriter = new StringWriter(niceString);
XmlTextWriter xmlWriter = new XmlTextWriter(strWriter);
xmlWriter.Formatting = Formatting.Indented;
xDoc.WriteTo(xmlWriter);
xmlWriter.Close();
strWriter.Close();
return niceString.ToString();
}
private static X509Certificate2 GetX509Certificate()
{
X509Certificate2 certificate2 = null;
var store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
var collection = store.Certificates;
var fcollection = collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
const string certificateThumbprint = "7dfbc7369306ed096b7e5c7b4ba6e99f190240e9";
store.Close();
if (fcollection.Count > 0)
{
foreach (var variable in fcollection)
{
if (variable.Thumbprint != null &&
variable.Thumbprint.Equals(certificateThumbprint, StringComparison.InvariantCultureIgnoreCase))
{
certificate2 = variable;
}
}
}
return certificate2;
}
private static string ReadConfig()
{
string path = System.AppDomain.CurrentDomain.BaseDirectory + "Edoc2Cloud.xml";
//string path = System.AppDomain.CurrentDomain.BaseDirectory + "VM-CreateVM.xml";
string s;
using (var sr = new StreamReader(path, Encoding.GetEncoding("GB2312")))
{
s = sr.ReadToEnd();
}
return s;
}
}
Here is the XML:
<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Name>EDoc2Test</Name>
<DeploymentSlot>Staging</DeploymentSlot>
<Label>EDoc2Testlabe</Label>
<RoleList>
<Role>
<RoleName>EDoc2TestRoleName</RoleName>
<RoleType>PersistentVMRole</RoleType>
<ConfigurationSets>
<ConfigurationSet>
<ConfigurationSetType>WindowsProvisioningConfiguration</ConfigurationSetType>
<ComputerName>computer-name</ComputerName>
<AdminPassword>APasswor_324d</AdminPassword>
<EnableAutomaticUpdates>true</EnableAutomaticUpdates>
</ConfigurationSet>
</ConfigurationSets>
<AvailabilitySetName>EDoc2TestSetName</AvailabilitySetName>
<OSVirtualHardDisk>
<HostCaching>ReadWrite</HostCaching>
<DiskName>SomeName-0-20121007173943</DiskName>
<MediaLink>http://portalvhdsx4flx9dhmjyt1.blob.core.windows.net/vhds/o3lceiy3.ioa201305211013360129.vhd</MediaLink>
<SourceImageName>o3lceiy3.ioa201305211013360129.vhd</SourceImageName>
</OSVirtualHardDisk>
<RoleSize>Medium</RoleSize>
</Role>
Based on the error you're receiving and the XML you've specified, can you please check if there is an image by the name o3lceiy3.ioa201305211013360129.vhd in your custom images? You could find that information by logging into the portal and going to Virtual Machines --> Images.
Documentation regarding <SourceImageName> parameter states that it is needed when you want to create a virtual machine either by using system or custom images.
You can read the complete documentation here: http://msdn.microsoft.com/en-us/library/windowsazure/jj157186.aspx#OSVirtualHardDisk.
Using the Google Docs Java API with a Google Apps account, is it possible to impersonate a user and download a file?
When I run the program below, it is clearly logging on to the domain and impersonating the user because it retrieves the details of one of the files and prints out the file title. However, when it tries to download the file, a ServiceForbiddenException is thrown.
If it is not possible with the Java API, does anyone know if it is possible for my program to write an HTTP request to download the file using the Protocol API?
public class AuthExample {
private static DocsService docService = new DocsService("Auth Example");
public static void main(String[] args)
throws Exception
{
String adminUser = args[0];
String adminPassword = args[1];
String authToken = args[2];
String impersonatedUser = args[3];
loginToDomain(adminUser, adminPassword, authToken);
URL url = new URL( "https://docs.google.com/feeds/" + impersonatedUser + "/private/full" );
DocumentListFeed feed = docService.getFeed(url, DocumentListFeed.class);
DocumentListEntry entry = feed.getEntries().get(0);
String title = entry.getTitle().getPlainText();
System.out.println( title );
String type = entry.getType();
if ( type.equals("document") )
{
String encodedAdminUser = URLEncoder.encode(adminUser);
String resourceId = entry.getResourceId();
String resourceIdNoPrefix = resourceId.substring( resourceId.indexOf(':')+1 );
String downloadUrl =
"https://docs.google.com/feeds/download/documents/Export" +
"?xoauth_requestor=" + encodedAdminUser +
"&docId=" + resourceIdNoPrefix +
"&exportFormat=doc";
downloadFile( downloadUrl, title + ".doc" );
}
}
private static void loginToDomain(String adminUser, String adminPassword, String authToken)
throws OAuthException, AuthenticationException
{
String domain = adminUser.substring( adminUser.indexOf('#')+1 );
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(domain);
oauthParameters.setOAuthConsumerSecret(authToken);
oauthParameters.setOAuthType(OAuthType.TWO_LEGGED_OAUTH);
oauthParameters.setScope("https://docs.google.com/feeds/ http://spreadsheets.google.com/feeds/ http://docs.googleusercontent.com/");
docService.useSsl();
docService.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());
docService.setUserCredentials(adminUser, adminPassword);
}
// Method pasted directly from Google documentation
public static void downloadFile(String exportUrl, String filepath)
throws IOException, MalformedURLException, ServiceException
{
System.out.println("Exporting document from: " + exportUrl);
MediaContent mc = new MediaContent();
mc.setUri(exportUrl);
MediaSource ms = docService.getMedia(mc);
InputStream inStream = null;
FileOutputStream outStream = null;
try {
inStream = ms.getInputStream();
outStream = new FileOutputStream(filepath);
int c;
while ((c = inStream.read()) != -1) {
outStream.write(c);
}
} finally {
if (inStream != null) {
inStream.close();
}
if (outStream != null) {
outStream.flush();
outStream.close();
}
}
}
}
Impersonation will work as intended if you use Oauth2 with ServiceAccounts