How to redirect user from OWIN middleware? - c#

I have middleware used for authentication purposes and need to distinguish users by the type if they are internal or external. After this I want to redirect external users to custom error page, because they should not have access to particular section of my site.
I wanted to throw HttpResponseException with my custom status code and handle it by linking in web config's section customErrors with my error page. However I cannot use custom status code this way and to use one of the existing codes is bad idea in my case.
To be honest I am quite new to OWIN middleware and I am not even sure what to google. I will be most grateful for hints how to solve such situation.

Hey take a look at this:
public void Configuration(IAppBuilder app)
{
ConfigureApp(app);
//Some other code here
if (_helper.IsNew())
{
Debug.Write("This is a new guy. Redirect him to the setup page permanently");
var ctx = new OwinContext();
ctx.Response.Redirect("/Setup");//This is how I redirect from Startip.cs
}
}
Observe the code where I am checking in IF for truthy, on true I will create a new OWIN CONTEXT and do redirect there.
I can also specify the redirection status code: 301/302. But without that also the above code works just fine

You should be able to set response code (303 See Other) to the response object in middle-ware and a location header to where you want to redirect user.
When you do that based you you business logic you should not call next function and user will be redirected to new location (if no other middle-ware down the stack will change the response).
Remember to register your middle-ware before web api or mvc.
You can google for web api building custom middleware. Here is an example article you could find Writing Custom Middleware for ASP.NET.

Related

How to delete a specific cookie on startup, using .net core 2?

I need to delete a specific cookie when my app starts, before heading to home page.
I had this inside a controller action method, with a redirect to home page, setting up my startup class to use as route template this controller and action method.
However, there must be a way I can set up a method to delete this cookie, and execute it from startup?
In ASP.NET, this would be done in the methods of global.asax (often in Session_Start(...)). Read more here and here.
In ASP.NET Core, the startup.cs class is where all configurations of services are defined, as well as pipeline requests are managed.
You need to make your own custom middleware for this. Middleware is software that's assembled into an app pipeline to handle requests and responses.
There is another SO question on this topic here (with an answer):
ASP .NET Core webapi set cookie in middleware
For more in-depth cookie management look at this article:
https://www.seeleycoder.com/blog/cookie-management-asp-net-core/
More on middleware:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-2.2

Hide Web Page From Public - WebMatrix 3

I am using C# Razor in order to make a social network. There are wepages that contain sensible data and I don't want someone to go to that url and see it. Not even by going to the Inspect Element and open it through there. So is there a way to warn the user that "This web page is not allowed"?
You have to implement authentication and authorization in order to control who can actually access any given route in an mvc application. I can only recommend that you start by reading the official site www.asp.net/mvc/overview/security about authorization and authentication.
With the proper authentication/authorization the server will simply not send any data, or you could redirect to a specific "not allowed page"
I agree with Louis, you should get this book here which helped me a ton. http://www.apress.com/9781430257523
The literal answer you are looking for concerns the use of authorization attributes you place above controller actions or controllers themselves. So an action might look like this
[Authorize]
public ActionResult UserAccount(Guid id){...}
By setting up authentication using ASP.Net Identity you will be able to automatically redirect visitors who are not logged in to another page etc.
Also if you need to make sure that the current logged in user is not going to (for example) another user's personal page (account settings?) you would do a simple check on the server side to prevent this. Something like so (Pseudo code)
if(User.Identity.GetUserId() != account.OwningUserId)
return RedirectToAction("404", "Shared");

C# Web API - Security for some of the GET requests

On an existing host I've added Web API Models & Controllers. I've added the following four:
Products
Orders
Categories
Users
When someone accesses the localhost:port\api\products, it returns all the products in JSON format.
The Create, Update and Delete statements are completely disabled, so we are only able to use GET-requests on the API (so either \api\products for a list of all products or api\products\# for a single products with id #).
Because the other CRUD's aren't used, there isn't a lot of security that should be added to the Web API, except for one thing: The Users
These will also return emails and such, which would be better to keep private and unreadable without the proper authorization (without entire log-in pages, but a way to authenticate yourself when accessing the Web API in for example Android HttpGetRequests).
So, the question: How should I add authorization for only the UsersController accessed by the Web API.
And, how can I encrypt the JSON in C# and decrypt it in Android again. If this second part is too big to answer I'll make a new question later on, my main focus is the low-end [<- without log-in pages, so built in into the GET-request] authorization of the Web API's GET-request for Users.
Edit 1: I did found this link where a new project is made with Authorization Changed to Individual Users. I also see that the user is registered and then logged in with POST and GET requests.
The following questions came into mind when reading through this link:
How to change the Web API's Authorization to Individual Users on an existing project?
Our authorization is done through OAuth (mainly Google-account) with our work e-mail address. I guess it's not possible / easy to authorize in the same way as in the link with a Google-account on Web API GET-requests.
Edit 2: After using the first link provided by Vladimir Gondarev I've added the [Authorize] to both the Get methods in the UsersController. In my project everything else was already used before, like a class that uses the AuthorizeAttribute, so just adding the [Authorize] was already enough for the first step. Now in the browser I get an unauthorized (JSON) back when I'm not logged in, which is good.
The next step would be to add the OAuth-authorization to the Android app, but that is an entire new problem / question that I will look into first before asking a new stackoverflow-question.
The simplest solution would be "Basic Authentification". In order to to implement it you have to derive from AuthorizeAttribute and then apply it to a method or a controller.
Here you find further info:
What is basic Authentification:
http://www.asp.net/web-api/overview/security/basic-authentication
Implementation:
ASP.net Web API RESTful web service + Basic authentication
You don't have to encrypt anything as long as you use HTTPS transport.

Authorization through a ASP.NET Web API in Orchard CMS

Creating an ASP.NET Web API module in Orchard CMS is simple and straightforward. The following link explains how to do it and it works just fine. http://www.sebastienros.com/web-api-makes-it-in-orchard
However, the GET requests does not work when the WebAPI is running under Orchard and you use the [Authorize] attribute at the same time.
[Authorize]
public IEnumerable<string> Get()
{
return _moduleManager.GetUsers().Select(n => n.UserName);
}
When I call this from the client
HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential("user", "password");
HttpClient client = new HttpClient(handler);
var response = await client.GetAsync("http://localhost:30321/OrchardLocal/api/MyWebAPIModule/Users");
Console.WriteLine(response);
the response variable returns to me the "Not found" HTML page from Orchard. Without the [Authorize], it returns a list of users.
Does Orchard have something already built-in to match the credentials with a registered user in Orchard? Or is there steps missing in the process?
This blog post may be a helpful resource for a deeper understand ASP.NET's Authorize attribute. It might help to look in the web.config file to see what the authentication mode is set to.
I think the problem is that if you are making a call in code, you need to pass any cookies in the request.
A user is authenticated against the website by the use of the aspnetAuth (or FedAuth) cookie, which is provided by the browser. So if you called /OrchardLocal/api/MyWebAPIModule/Users from the browser you would expect this to work (you should see this happen in fiddler by looking at the headers/cookies).
However if you make a call in code you need to pass cookies/auth. header yourself. The call you have does not have any of this, thus it fails (you should see the absence of the cookie in fiddler for this request).
I'm not sure why you would call the api in this way from within your own module. Presumably the API controller calls a service that does the actual workload. You could call this service directly from your Driver/Action, still safe in the knowledge that your business logic is behind the service interface.

Using redirect from an HttpModule in an MVC web site, the "right" way

In the old days:
We used Response.Redirect, which sets the 302 response header and raises a ThreadAbortException to prevent anything else from happening after the redirect.
Now, with MVC:
We return a RedirectResult, which avoids the performance issues with ThreadAbortException and also allows the rest of the pipeline to inspect the results before actually sending them back to the browser. It's a different way of thinking about a redirect-- now instead of halting execution, a redirect is more like returning from a function.
My question has to do with mixing and matching these patterns.
Here's the requirement. We have an MVC site, and site contains an HttpModule that is in charge of authentication. If anything goes wrong with authentication, it drops cookies and redirects to an external web page. So the HttpModule makes a decision whether to send the redirect header or pass control to the MVC site. If it sends the redirect header, it has to halt execution-- if authentication failed, we don't want the site to be accessible in any way, shape, or form.
What's the "right" way to do this? Should the HttpModule simply use Response.Redirect just like we have always done? Or is there some clever way to accomplish this that is more consistent with the MVC pattern? Is there any way for the HttpModule to tell the pipeline to stop processing?
Or should I be using some completely different pattern, something that doesn't use an HttpModule? Perhaps an MVC filter? The thing is, the modularity/separation of concerns between the module and the site itself is very important. Anyone have any recommendations?
Thought I'd throw the answer up here in case anyone else has a question in a similar problem domain.
The answer is actually very simple.
HttpContext.ApplicationInstance.CompleteRequest()
The above call no longer throws a ThreadAbortException (this changed with .NET 2.0) so you can safely use it to tell the pipeline to halt execution. When the HttpModule exits, the web site proper is bypassed and control goes directly to EndRequest-- exactly what I needed. This was not possible in .NET 1.1 but I don't think there are a lot of 1.1 MVC projects out there ;)
Since you mentioned this was for authentication, you should use the Authorize Attribute. You can use it either at the Class level or the Action level.
[Authorize]
public class HomeController : Controller
{
// All actions will require authorization
}
public class ImageController : Controller
{
public ActionResult PublicImage()
{
}
[Authorize]
public ActionResult ImageRequiringAuth()
{
}
}
For your use case, you may need to inherit from the AuthorizationAttribute, as described in this answer.

Categories

Resources