Using WebClient to get a intranet files - asp.net

In our I have company intranet a server, that is responsible for storing files. Initially, the server had to operate only in an intranet environment, but now there is a need to share files with external web applications. Making this server accessible from the internet is not an option.
I want to create a ASP.NET MVC solution that uses the WebClient to get these files from the intranet server and send back them to the user through FileResult of the external app. This client would be provided with custom domain user credentials. So far I have tried to create a CredentialCache class, set correct credentials and append it to WebClients Credentials property like in the following code:
public ActionResult Download(int id, string fileName)
{
var fileService = new FilesService();
var documentUrl = fileService.GetUrlFileByFileId(id);
string filePath = "http://my.intranet.com/" + documentUrl;
var fileNameFromUrl = filePath.Substring(filePath.LastIndexOf("\\") + 1);
byte[] filedata;
CredentialCache cc = new CredentialCache();
cc.Add(new Uri("http://my.intranet.com/"),
"ntlm",
new NetworkCredential("myUserName", "myPassword", "myDomain"));
using (var client = new WebClient())
{
client.Credentials = cc;
filedata = client.DownloadData(filePath);
}
string contentType = MimeMapping.GetMimeMapping(filePath);
var cd = new ContentDisposition
{
FileName = fileName,
Inline = false
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(filedata, contentType);
}
According to the question posted in Domain credentials for a WebClient class don't work it should work, but it’s not. It’s running only if I run the problem on localhost, but when I publish my solution on a test server, it return 401 error. My question is did how to get this working? And is it possible to download files through this method?
UPDATE--- I've published my test app on another server and it started to working. Now the test app is on another server than the server That stores files. Any ideas why it's not working when both are on the same machine?

401 error is unauthorized, so perhaps the issue is related to permissions. Are you sure the user account you are using to login to that folder has the proper access?

Ok, I found the solution on this site: https://blogs.msdn.microsoft.com/distributedservices/2009/11/10/wcf-calling-wcf-service-hosted-in-iis-on-the-same-machine-as-client-throws-authentication-error/
The solution was to add an registry entry and add my web apps to this entry to allow back connections.

Related

Using an asp web api in wpf

So i have got a simple question, when using our cms we can attach a driver as an executable.
The driver we want to make is an httpreceiver or just an api endpoint. SO i tought lets use asp.net web api for it -> using version .net 4.6.1. altough asp.net application requires a webserver and is not an executable, But i read on google you can use it inside a wpf application since our cms is wpf in the first place.
So my question is is there a way i can use my mvc web api project inside a wpf application? and if not what would be the best bet to have an httpreceiver or httppost receiver into an executable?
Main reason is we want to send httppost requests to the server as a desktop application. I know it's complicated but thats how it needs to be as far as I know.
In the case where asp is not an option, what the best way to make a postreqst/ httpreceiver as a desktop application?
EDit:
the resource guide from microsoft beneath was perfectly however i still have a question:
string baseAddress = "http://localhost:9000/";
// Start OWIN host
using (WebApp.Start<Startup>(url: baseAddress))
{
// Create HttpClient and make a request to api/values
HttpClient client = new HttpClient();
string username = "test".ToUpper().Trim();
string password = "test123";
//Mock data
var body = new PostTemplate1();
body.Description = "test";
body.StateDesc = "httpdriver/username";
body.TimeStamp = DateTime.Now;
body.Message = "This is a post test";
var json = JsonConvert.SerializeObject(body);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var authToken = Encoding.ASCII.GetBytes($"{username}:{password}");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authToken));
var response = await client.PostAsync(baseAddress + #"api/Post", data);
var result = response.StatusCode;
}
As the guide says you post to url with port 9000
is there a possibility to use another port and use https?
if yes where to manage certificates for handling https?

when I use asmx service and SSRS report service I am getting "The request failed with http status 401: unauthorised"

I was trying to call report related service (asmx) from my asp.net web application by running locally.
Then an exception happened saying. The request failed with http status401:unauthorised.
In my analysis I understood the issue caused due to below code
SSRSWebService.ReportingService2005 rs = new SSRSWebService.ReportingService2005();
rs.Credentials = new MyReportServerCredentials().NetworkCredentials;
and
Uri reportUri = new Uri(ConfigurationManager.AppSettings["ReportServerManagement.ReportingService2005"]);
this.rptViewer.ServerReport.ReportServerCredentials = new MyReportServerCredentials();
In my detailed analysis I understood that the issue was because of the credential set up in serviceObject.credential OR ServerReport.ReportServerCredentials was wrong. This can be rectified in two different way either by setting credential to default with below code
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;//"rs" is report object
Or locate below code and set up proper authenticated user credential in the code
public WindowsIdentity ImpersonationUser
{
get
{
// Use the default Windows user. Credentials will be
// provided by the NetworkCredentials property.
return null;
}
}
public ICredentials NetworkCredentials
{
get
{
// Read the user information from the Web.config file.
// By reading the information on demand instead of
// storing it, the credentials will not be stored in
// session, reducing the vulnerable surface area to the
// Web.config file, which can be secured with an ACL.
// User name
string userName =
<<AccurateUserName;>>
// Password
string password =
<<AccuratePassword;>>
// Domain
string domain = <<AccurateDomainName;>>
return new NetworkCredential(userName, password, domain);
}
}
In order to check whether which user has the access, we need to type service url ending with asmx (http:/MyServiceHostedServer/MyService.asmx) in a web browser. It will prompt a user name and password . Give our username as :Domain\Username and password.If we are able to see wsdl xml file then that user has the access.

Dot Net Client and IIS hosted SignalR with Win auth

Is there a way to configure the .NET client so that it will work with a IIS hosted SingalR that uses Windows authentication?
If I disable windows authentication it works, but this is not an option
setting connection.Credentials = CredentialCache.DefaultCredentials does not help.
The code
public EventProxy(IEventAggregator eventAggregator, string hubUrl)
{
typeFinder = new TypeFinder<TProxyEvent>();
subscriptionQueue = new List<EventSubscriptionQueueItem>();
this.eventAggregator = eventAggregator;
var connection = new HubConnection(hubUrl);
connection.Credentials = CredentialCache.DefaultCredentials;
proxy = connection.CreateHubProxy("EventAggregatorProxyHub");
connection.Start().ContinueWith(o =>
{
SendQueuedSubscriptions();
proxy.On<object>("onEvent", OnEvent);
});
}
ContinueWith triggerst directly after Start and when the first subscription comes in I get a
The Start method must be called before data can be sent.
If I put a watch on the DefaultCredentials I can see that Username, Domain and Password are all String.Empty. Its a standard Console program, Enviroment.Username returns my username
Sure, set connection.Credentials = CredentialCache.DefaultCredentials. More details about credentials here http://msdn.microsoft.com/en-us/library/system.net.credentialcache.defaultcredentials.aspx.

Publishing with Core Service and Impersonation

I have a Tridion Core Service Web Application to publish pages. When logged into the server and running it from there via a browser client calling a web service with ajax it works fine. However, when I run the application from my desktop it does nothing, and also throws no error messages.
*Edit:
The Web App hosting the web service is running as an 'Application' under the Tridion 2011 CMS website. This is done to avoid cross-domain ajax issues/
Update: The code below is working fine - both with the impersonate and also with Nick's solution. My issue was actually in how I was calling the web service from jQuery and using the appropriate URL. I am leaving the code and question so maybe it will help others.
My code is:
string binding = "wsHttp_2011";
using (var client = new SessionAwareCoreServiceClient(binding))
{
client.Impersonate("company\\cms_svc");
// ** Get Items to Publish
List<string> itemsToPublish = GetItemsToPublish(publishItem.TcmUri, client);
PublishInstructionData instruction = new PublishInstructionData
{
ResolveInstruction = new ResolveInstructionData() { IncludeChildPublications = false },
RenderInstruction = new RenderInstructionData()
};
PublicationTargetData pubtarget = (PublicationTargetData)client.Read(publishItem.PubTargetUri, readoptions);
List<string> target = new List<string>();
target.Add(pubtarget.Id);
client.Publish(itemsToPublish.ToArray(), instruction, target.ToArray(), GetPublishPriority(publishItem.Priority), readoptions);
}
Have at look at this page on SDL Live Content, which explains various types of scenarios for connecting as different users:
http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL_Tridion_2011_SPONE/task_87284697A4BB423AAD5387BBD6884735
As per the docs, instead of impersonation you may want to establish your Core Service connection as follows using NetworkCredential:
using (ChannelFactory<ISessionAwareCoreService> factory =
new ChannelFactory<ISessionAwareCoreService>("netTcp_2011"))
{
NetworkCredential networkCredential =
new NetworkCredential("username", "password", "domain");
factory.Credentials.Windows.ClientCredential = networkCredential;
ISessionAwareCoreService client = factory.CreateChannel();
Console.WriteLine(client.GetCurrentUser().Title);
}

asp.net web api: accessing uploaded file stream

I have an asp.net web api application which is acting as a Relay to a wcf web service. In certain scenarios I want to upload large files. The methods in the wcf service accept files as stream.
I do not want to save the files on my intermediate server I want to access the stream of the uploaded file and provide it to the wcf method so that the data is directly streamed to the wcf service.
Here is similar scenario when client is downloading the file
using (IProductsChannel channel = ChannelFactory.CreateChannel())
{
result.Content = new StreamContent(channel.GetFile());
result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
return result;
}
Here is at least one way of doing it. using the HTTPContext the only problem with this one is that it is not good for unit testing so we have to abstract it out in the final solution.
var file = HttpContext.Current.Request.Files[0];
var result = new HttpResponseMessage(HttpStatusCode.OK);
using (IProductsChannel channel = ChannelFactory.CreateChannel())
{
channel.SaveFile(file.InputStream);
}
return new HttpResponseMessage(HttpStatusCode.Created);
}

Resources