need application url from console application - asp.net

I have a MVC web application and a console application created as a separate project inside my web application. I want this console application to be run as a windows service at specified intervals. The console application is for sending mail to some persons. I need to include my application URL in the mail content body which redirect to my application login page. Since i am running this service for more than one instance i could't hard code the URL in code. Someone please help. I tried the below code. But it is returning null value.
var site = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.ApplicationPath.TrimEnd('/');
var url = string.Format("<a href='{0}'>Login</a>", site);

I converted this from the comment to the question.
You are trying to obtain information from HttpContext.Current in situation when there is no HttpContext available at all - because your console application is launched directly by the operating system and not on the event of incoming http request (as oposed to request handling in your MVC application) - so there simply is no http context to use (hence HttpContext.Current is null in your console application).
You have to establish your own application logic for your console application that determines which URL to use in your emails. What would that be depends on the answer to the question "what does the url to be used in each email depend on specifically"? In other words - "how should each email know what URL to use"? Once you figure out the answer to that question then you can think of how to pass that dependency to your windows service.
Example (I do not know if it describes your case):
there are several web applications on different URLs
each of these web applications can add email to the queue to be send
windows service (console app) is scheduled to run once in a while and process the queue by sending the emails. Each email has to have an URL of the application from where it was added.
Assuming the example above you can just add the email together with the URL of the application to the queue (insted of just the email) and then retrieve that information from the queue in your console application. So then each of the emails has associated URL. It is irrelevant how would the queue itself be implemented (SQL, file, ...).

Related

get signalr hub endpoint url in asp.net mvc (where hub is hosted)

I have an asp.net mvc 5 web app that hosts my signalr (v2) hub/server. This web app kicks off a console app that needs to connect to the hub. How can I get the full url to my signalr hub from within the web app so that I can pass it as an argument to my console app?
Or is there a better way for my console app to know what the url of the hub is?
Thanks!
The answer I was looking for is:
string hubUrl = string.Format("{0}://{1}{2}signalr", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));
The "signalr" part of the string is the default path to your endpoint. If you changed the default endpoint path, then you need to update that part of the string.

ASP.NET MVC with Forms Auth and WebApi with Basic Auth

I have a WebApi using Basic Auth nicely. And I have an MVC site using Forms Auth nicely. But here's the catch:
Client X has a dedicated database with any number of Contacts and Products. The MVC site is a dedicated site for them (via {clientId} routing), which allows their Contacts to log in (via Forms Auth) and place orders for their products. The Contact must be Form-ly logged in to place an order.
The product orders (need to) hit the WebApi to be recorded in the Client's database.
But since the WebApi uses Basic Auth to validate the Client, not the Contacts who placed the orders, every request comes back is 401 - Unauthorized.
I've checked out ThinkTecture as suggested by a number of posts here on SO, however it doesn't get me what I need because I'm not looking to allow Forms Auth in the WebApi. I don't want to authenticate the Contact from the Client's database in the WebApi, I want to authenticate the Client in the WebApi.
Has anyone come across a similar scenario and am I missing something glaringly obvious? Perhaps I need to implement both Forms and Basic on the site?
The very standard Api call I'm making from the site (where the UserName and Password are the Client's, not the Contact's):
var clientId = new Guid(RouteData.Values["clientId"].ToString());
var baseUrl = ConfigurationManager.AppSettings["ApiBaseAddress"];
var authHeader = Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", _shoppingCartSettings.UserName, _shoppingCartSettings.Password)));
var requestUrl = String.Format("api/{0}/inventory", clientId.ToString());
var httpWebRequest = WebRequest.Create(baseUrl + requestUrl);
httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, "Basic " + authHeader);
httpWebRequest.Method = "GET";
httpWebRequest.Accept = "application/json";
httpWebRequest.ContentType = "application/json";
try
{
using (var httpWebResponse = httpWebRequest.GetResponse())
{
// we never get here because of a 401
}
}
catch (WebException ex)
{
using (var httpWebResponse = ex.Response)
{
// we always get here
}
}
If I set up a separate test client and make the same call, it works great :/
Is your Web API under the same virtual directory and configuration as the MVC site? It looks like the Forms Auth HTTP module kicks in for your API, which you don't want. As long as you don't plan to call the API directly from the browser, move it to a separate virtual directory that is set up exclusively for basic auth, no forms auth module in the web.config for the API.
Why not have one login for your MVC site that has the ability to submit orders for every Client? It makes sense for your WebAPI to only allow Clients to submit orders for themselves. But I don't think it makes sense to have your MVC site authenticate as different Clients based on the Contact. Your MVC site would have to store the passwords for each Client.
Instead, create one login for the MVC site and give it the ability to submit an order for any Client.
After much banging of head against the not-so-proverbial wall, and a much needed shove by #0leg, I've discovered the cause.
In the Properties of my WebApi project file under Web > Servers, the Visual Studio Development Server was being used with a Virtual Path of "/", whereas my MVC project file was set up to use the Local IIS Web Server. The MVC project also had the Apply server settings to all users (store in project file) option checked.
Setting both to use the local IIS server resolved it.
Upon further contemplation, this now seems logical since they were essentially running on different servers.
Posting this for posterity's sake.

Restful Web API from Browser

I am using ASP.NET MVC 4 WEB API to create a Restful API service. This is my first go at it, so if you feel I am taking a wrong approach please feel free to correct.
I want to create a rest API (only & not a website, the consumer of the api can decide where they want to consume it), in the past I have used Restful WCF service to achieve this.
I have created a new ASP.NET MVC 4 Web Application and chose the WebAPI project template. I have added a controller class 'CatalogueController.cs' the purpose is on Get() operation I want to return the Catalogue list. The CatalogueDo contains only one property 'Service' of type string.
[System.Web.Http.HttpGet()]
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK, Catalogue);
}
When I run the application the browser loads with the URL http://localhost:5502/ resource not found, if I add the controller name http://localhost:5502/Catalogue/ the browser pops open a notepad with,
[{"Service":"Exchange"},{"Service":"Holidays"}]
The data is correct but
the browser keeps showing resource not found and after my request has been served the URL changes to http://localhost:5502/.
Question,
Am I doing something wrong? Should the response that pops up in the
notepad not be shown as xml in the browser it self?
Why does the controller name get removed from the URL once the request has been served?
Is it at all possible to invoke this REST service from Excel or Power Pivot?

Passing security exception back to client when using role based authorisation in WCF

I am creating a WCF (with callbacks) service currently hosted as a process but will be a service eventually.
I am using netTCP binding in a Windows Domain environment and the client is on another machine within the domain (windows forms client).
I have all the binding, methods etc working with Windows security at transport level and an SPN in place.
I am now implementing security and am attempting to use this pattern on some methods (not all need to be secured):
<PrincipalPermission(SecurityAction.Demand, Role="MyDomain\DataReader")>
public Function GetData() As String
return "Test String"
End Function
(example)
This correctly allows users and blocks those not in role.
My problem is that an exception is raised at the service end (I can see this in VS as the process is run from there). The client does not get an security exception but times out instead.
How do I correctly pass back to the caller that a security exception occurred so that the I can then pass a message to the user.

HTTP Error 401.1 when using WinHttp.WinHttpRequest.5.1 in classic ASP site

General information
Operating System: Windows Server 2003 R2 Service pack 2
Webserver: IIS 6
NTAuthenticationProviders: NTLM only
Webapplication: Classic ASP
Browsers used: IE7, IE8, IE9
There’s a Classic ASP web application called knowledgebase, within an IIS website called eblcplaza like so: eblcplaza/knowledgebase/.
eblcplaza has anonymous access AND Integrated Windows Authentication enabled.
knowledgebase has anonymous access disabled and Integrated Windows Authentication enabled
knowledgebase is a Classic ASP application has its own Application pool which runs under the predefined Application pool identity “Network service”
When I’m logged in with my NT account I can access any page I want just fine. The problem is with the WinHttp.WinHttpRequest.5.1 component. It’s used in some parts of knowledgebase to do a server side request to retrieve content from some .asp scripts which reside within the web application.
The problem started when Anonymous access was turned off on knowledgebase . Note, turning it back on is not an option.
Example of a request using WinHttpRequest:
set WinHTTPRequest = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
WinHTTPRequest.SetTimeouts 20000, 20000, 20000, 20000
call WinHTTPRequest.Open("POST", someUrlToAspScript, false)
WinHTTPRequest.SetAutoLogonPolicy 0
WinHTTPRequest.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
WinHTTPRequest.Send strQueryString
Response.Write(WinHTTPRequest.ResponseText)
With SetAutoLoginPolicy set to 0, I get the following error message on the pages where WinHttpRequest is used:
You do not have permission to view this directory or page using the credentials that you supplied.
HTTP Error 401.1 - Unauthorized: Access is denied due to invalid credentials.
Internet Information Services (IIS)
With SetAutoLoginPolicy set to 2 (Do not automatically send user credentials according to MSDN), I get the following error message on the pages where WinHttpRequest is used:
You do not have permission to view this directory or page using the credentials that you supplied because your Web browser is sending a WWW-Authenticate header field that the Web server is not configured to accept.
HTTP Error 401.2 - Unauthorized: Access is denied due to server configuration.
I know for a fact that my NT user account has the proper rights to access those .asp scripts and so does the Network Service account.
I tried figuring out what could be the problem for several days know, tried setting the NTAuthenticationProviders to only NTLM and both Negotiate and NTLM amongst other things, but nothing worked so far.
Please help me out, It’s starting to drive me crazy.
Regards,
Bart
I guess the pages in knowledgebase are accessed with the anonymous account where you start from at eblcplaza. Try to enable NTLM only on the page in eblcplaza where you use the request, you can do that on that file only. Like that your credentials get passed to knowledgebase. On both pages log the Session("username") variable.
First of all let's clear up what it is you asking the server to do. It will have demanded your credentials from the client with which it is now impersonating you for security purposes. The WinHTTP request it is making to a service (WinHTTP doesn't know that its the exact same application) that now demands credentials. What you want this impersonating thread to do is use your creds to authenticate against an "external" service.
I suspect that what is happening here is that the server is not cleared to re-use your credentials in this way. If I recall correctly (which may not be that certain) a server needs to be granted the right to delegate in order to do that. It may also be possible to allow this if Kerberos is used instead of NTLM to perform windows integrated security.
However all that may be academic. You should understand that an app making a http request to itself has the potential to hang when under load in a way that would require a recycle to release.
Consider this alternative. Given that ServicePage.asp is a page used both directly by the browser and by an internal ClientPage.asp do the following.
Rip out the service code from ServicePage.asp and place in a VBScript class in a new ServiceInclude.asp. Now add the this ServiceInclude.asp as an include file in ServicePage.asp where ServicePage.asp only contains the plumbing necessary to instance the class and use it to generate its output.
Modify ClientPage.asp so that instead of attempting WinHttp to ServicePage.asp it simply includes the ServiceInclude.asp, instances the contained class and uses the class to provide the service required.

Resources