C# Download File from HTTP File Directory getting 401 error or 403 error - webclient

I’m trying to download several files from a local network device:
http file directory
I want to write a code that will automatically download all those .avi files to my pc drive.
I have 2 problems:
Problem 1: AUTHENTICATING using WebClient class only.
If I use WebClient class only to connect, I get a 401 Unauthorized error.
Code:
try
{
using (WebClient myWebClient = new WebClient())
{
myWebClient.UseDefaultCredentials = false;
myWebClient.Credentials = new NetworkCredential("user", "pword");
String userName = "user";
String passWord = "pword";
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + passWord));
myWebClient.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials;
Console.WriteLine("Header AUTHORIZATION: "+ myWebClient.Headers[HttpRequestHeader.Authorization].ToString());
// Download the Web resource and save it into the current filesystem folder.
Console.WriteLine("Start DL");
myWebClient.DownloadFile("http://192.168.2.72:81/sd/20170121/record000/P170121_000000_001006.avi", "P170121_000000_001006.avi");
Console.WriteLine("End DL");
}
}
catch(Exception ex)
{
Console.WriteLine("DOWNLOAD ERROR: " + ex.ToString());
}
Error Message: Failure to authenticate
401 Unauthorized Error
Problem 2: Was able to authenticate using WebProxy class but can’t download . Getting 403 Not found error.
Code:
try
{
using (WebClient myWebClient = new WebClient())
{
WebProxy wp = new WebProxy("http://192.168.2.72:81/sd/20170121/record000/",false);
wp.Credentials = new NetworkCredential("user","pword");
Console.WriteLine("Web Proxy: " + wp.Address);
myWebClient.UseDefaultCredentials = false;
myWebClient.Credentials = wp.Credentials;
myWebClient.Proxy = wp;
Console.WriteLine("Downloading File \"{0}\" from \"{1}\"\n\n", filename, wp.Address);
// Download the Web resource and save it into the current filesystem folder.
Console.WriteLine("Start DL");
myWebClient.DownloadFile("http://192.168.2.72:81/sd/20170121/record000/P170121_000000_001006.avi", "P170121_000000_001006.avi");
Console.WriteLine("End DL");
}
}
catch(Exception ex)
{
Console.WriteLine("DOWNLOAD ERROR: " + ex.ToString());
}
Error Message: 403 Not Found
DOWNLOAD ERROR: System.Net.WebException: The remote server returned an error: (404) Not Found.
at System.Net.WebClient.DownloadFile(Uri address, String fileName)
at System.Net.WebClient.DownloadFile(String address, String fileName)
at ConsoleApplication2.Program.Main(String[] args) in C:\Users\Gordon\documents\visual studio 2015\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 139
Please help me identify if there are any mistakes in my code or is there a better way to submit credentials and download all the files.
Thanks in advance!

I'm not Dot Net developer, I'm just sharing my opinion.
In the second point you have mentioned that you are getting 403 which is the Http status code for Acces Denied. I feel your credentials are not valid or you don't have privilege to do the operation.

Related

RESTful client in Unity - validation error

I have a RESTful server created with ASP.Net and am trying to connect to it with the use of a RESTful client from Unity. GET works perfectly, however I am getting a validation error when sending a POST request. At the same time both GET and POST work when sending requests from Postman.
My Server:
[HttpPost]
public IActionResult Create(User user){
Console.WriteLine("***POST***");
Console.WriteLine(user.Id+", "+user.sex+", "+user.age);
if(!ModelState.IsValid)
return BadRequest(ModelState);
_context.Users.Add(user);
_context.SaveChanges();
return CreatedAtRoute("GetUser", new { id = user.Id }, user);
}
My client:
IEnumerator PostRequest(string uri, User user){
string u = JsonUtility.ToJson(user);
Debug.Log(u);
using (UnityWebRequest webRequest = UnityWebRequest.Post(uri, u)){
webRequest.SetRequestHeader("Content-Type","application/json");
yield return webRequest.SendWebRequest();
string[] pages = uri.Split('/');
int page = pages.Length - 1;
if (webRequest.isNetworkError || webRequest.isHttpError){
Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
}
else{
Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
}
}
}
I was trying both with the Json conversion and writing the string on my own, also with the WWWForm, but the error stays.
The error says that it's an unknown HTTP error. When printing the returned text it says:
"One or more validation errors occurred.","status":400,"traceId":"|b95d39b7-4b773429a8f72b3c.","errors":{"$":["'%' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0."]}}
On the server side it recognizes the correct method and controller, however, it doesn't even get to the first line of the method (Console.WriteLine). Then it says: "Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ValidationProblemDetails'".
Here're all of the server side messages:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://localhost:5001/user application/json 53
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'TheNewestDbConnect.Controllers.UserController.Create (TheNewestDbConnect)'
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3]
Route matched with {action = "Create", controller = "User"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult Create(TheNewestDbConnect.Data.Entities.User) on controller TheNewestDbConnect.Controllers.UserController (TheNewestDbConnect).
info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1]
Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.ValidationProblemDetails'.
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2]
Executed action TheNewestDbConnect.Controllers.UserController.Create (TheNewestDbConnect) in 6.680400000000001ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'TheNewestDbConnect.Controllers.UserController.Create (TheNewestDbConnect)'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished in 11.3971ms 400 application/problem+json; charset=utf-8
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
I have no idea what is happening and how to solve it. Any help will be strongly appreciated!
Turned out I was just missing an upload handler. Adding this line solved it: webRequest.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(JsonObject));

How to bypass SSL certificates issue in JBOSS REST ClientRequest

I'm new in Jboss, and using rest easy client for connection in my jboss code. Below is the code -
---
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
---
public String login() throws Exception {
---
String URL = "https://IP//service/perform.do?operationId=XXXXX";
ClientRequest restClient = new ClientRequest(URL);
restClient.accept(MediaType.APPLICATION_JSON);
restClient.body(MediaType.APPLICATION_JSON, hmap);
ClientResponse < String > resp = restClient.post(String.class);
if (resp.getStatus() != 201) {
throw new RuntimeException("Failed : HTTPS error code : " + resp.getStatus());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
new ByteArrayInputStream(resp.getEntity().getBytes())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
return output;
}
While connecting with SSL enabled server, getting certificate error "HTTP Status 500 - org.jboss.resteasy.spi.UnhandledException: javax.net.ssl.SSLException: hostname in certificate didn't match".
We can't change certificate at this moment, but is there any way to trust any certificate? I googled many posts, but nothing helped.
Anyone can tell me what is the solution of this issue.

Authorisation issue while accessing a page from repository in CQ5.

I'm trying to hit a page which contains a xml structure. for that i'm using this code
#Reference
private SlingRepository repository;
adminSession = repository.loginAdministrative( repository.getDefaultWorkspace());
String pageUrl = "http://localhost:4504"+page+".abc.htm";
conn = (HttpURLConnection)new URL(pageUrl).openConnection();
conn.setRequestProperty("Accept-Charset", charset);
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401"); // Do as if you'rusing Firefox 3.6.3
urlResponse = new BufferedInputStream(conn.getInputStream());
BufferedReader reader = new BufferedReader( new InputStreamReader(urlResponse) );
While accesing the page i'm getting this issue
org.apache.sling.auth.core.impl.SlingAuthenticator getAnonymousResolver: `Anonymous access not allowed by configuration - requesting credentials`
I'm logged in as an admin and whenever i'm directly hitting this urlfrom browser it is working properly bt while accessing it thriugh my code i'm getting this error.
any suggestion ?
If you are trying to call an url on an author instance, the following method I use in one of my projects might help (using apache commons HttpClient):
private InputStream getContent(final String url)
HttpClient httpClient = new HttpClient();
httpClient.getParams().setAuthenticationPreemptive(true);
httpClient.getState().setCredentials(new AuthScope(null, -1, null),
new UsernamePasswordCredentials("admin", "admin"));
try {
GetMethod get = new GetMethod(url);
httpClient.executeMethod(get);
if (get.getStatusCode() == HttpStatus.SC_OK) {
return get.getResponseBodyAsStream();
} else {
LOGGER.error("HTTP Error: ", get.getStatusCode());
}
} catch (HttpException e) {
LOGGER.error("HttpException: ", e);
} catch (IOException e) {
LOGGER.error("IOException: ", e);
}
}
Though at it is using admin:admin it only works on a local dev instance, if you are on a productive environment, I wouldn't put the admin password in plaintext, even though it is onyl code...
You are mixing up sling credentials & http credentials. While you are logged in at the sling-repository the http session is not aware of any authentication informations!

Can't upload file to Google Drive from service account

I am trying to upload a file to google drive using google service account.
Driver Service
public static Drive getDriveService(String secretKeyFile) throws GeneralSecurityException,
IOException, URISyntaxException {
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(DriveScopes.DRIVE)
.setServiceAccountPrivateKeyFromP12File(
new java.io.File(secretKeyFile))
.build();
Drive service = new Drive.Builder(httpTransport, jsonFactory, null)
.setHttpRequestInitializer(credential).setApplicationName("appl name").build();
return service;
}
Insert File
private static File insertFile(Drive service, String title, String description,String mimeType, String filename) {
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
Main Method
Drive service=null;
try {
String secretFile= "somedigit-privatekey.p12";
service = getDriveService(secretFile);
} catch (URISyntaxException ex) {
ex.printStackTrace();
}
File insertFile = insertFile(service, "test title", "File description", "text/plain", "c:\\test.txt");
List list = service.files().list();
System.out.println("Files Id : "+insertFile.getId());
System.out.println("Count Files : "+list.size());
Now, my questions is :
How and where can i check that file was uploaded?
Why it returns the file ID but list.size() is zero.
It returns the download link also but when i paste that link in
browser it doesn't download any file.
You are creating a listing request but not executing it. Use execute method to make the request:
service.files().list().execute();
If you paste the download link into the browser, it will respond with 401, because your download request should also contain a valid Authorization header. Use the following snippet to download the file programmatically.
HttpResponse resp = service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
InputStream stream = resp.getContent();
stream is an input stream for the file content.
Or add an Authorization: Bearer <access token> to the request you're making elsewhere.

Apache Abdera Client giving No credentials available for NTLM <any realm>#proxy.tcs.com:8080

I have seen many forum posts for this and tried several suggestions but still I am not able to solve this. The code works good at my home system, but behind the organization firewall it gives a exception message :
No credentials available for NTLM #proxy.tcs.com:8080
Here is the method which I am using
private static void UseAbdera() throws IOException
{
try
{
Abdera abdera = new Abdera();
AbderaClient client = new AbderaClient(abdera);
client.setProxy("OrgProxyHost", 8080);
NTLMAuthenticatorClass authenticator = new NTLMAuthenticatorClass("username", "password");
Authenticator.setDefault(authenticator);
NTCredentials ntcr = new NTCredentials("username", "password", "greenhouse.lotus.com", "India.TCS.com");
client.addCredentials("https://greenhouse.lotus.com", null, null, ntcr);
ClientResponse resp = client.get("https://greenhouse.lotus.com/forums/atom/service");
org.apache.abdera.model.Document<org.apache.abdera.model.Service> service_doc = resp.getDocument();
service_doc.writeTo(System.out);
System.out.println("\n");
org.apache.abdera.model.Service service = service_doc.getRoot();
org.apache.abdera.model.Collection collection = service.getCollection("Forums Feed Collection", "My Topics");
String coll_uri = collection.getResolvedHref().toASCIIString();
org.apache.abdera.model.Entry entry = abdera.newEntry();
entry.setTitle("TEST REPLY !");
// Mark private
resp = client.post(coll_uri, entry);
switch (resp.getType())
{
case SUCCESS:
String location = resp.getLocation().toASCIIString();
System.out.println("New entry created at: " + location);
break;
default:
System.out.println("Error: " + resp.getStatusText());
}
} catch (URISyntaxException ex)
{
Logger.getLogger(IBMConnectionMessages_ForumPractice.class.getName()).log(Level.SEVERE, null, ex);
}
}
This is the exception log I get
org.apache.commons.httpclient.auth.AuthChallengeProcessor selectAuthScheme
INFO: ntlm authentication scheme selected
Jul 6, 2012 10:42:03 AM org.apache.commons.httpclient.HttpMethodDirector processProxyAuthChallenge
INFO: No credentials available for NTLM #orgProxyHost:8080
Exception in thread "main" java.lang.IllegalStateException
at org.apache.abdera.protocol.client.CommonsResponse.(CommonsResponse.java:44)
at org.apache.abdera.protocol.client.AbderaClient.execute(AbderaClient.java:692)
at org.apache.abdera.protocol.client.AbderaClient.get(AbderaClient.java:216)
at org.apache.abdera.protocol.client.AbderaClient.get(AbderaClient.java:404)
at IBMConnectionMessages_ForumPractice.UseAbdera(IBMConnectionMessages_ForumPractice.java:231)
at IBMConnectionMessages_ForumPractice.main(IBMConnectionMessages_ForumPractice.java:45)
Please help, I have spent half a day on it.
your proxy may need ntlm authentication, so provide your proxy authentication details as NTCredentials while setting proxy credentials.