How to set up file download that requires authentication in ASP.NET? - asp.net

Do I have to create an API for token authentication or is there another way I can create some kind of login that would allow me to download a .csv file? I need a status code of 200 on successful authentication, otherwise the request should return a 401 status code and the file should not be downloaded. Does anyone have any advice on how I can achieve this? Ideally it should be as simple as possible to implement.

I have two suggestions about this.
You can put all download resources in the same folder, and the folder
will have a url pointing to it whether it is inside the application
or as an independent application. In the structure tree on the left
side of IISManager. As long as you select the folder and enable
authentication and disable Anonymous Authentication in the
Authentication module, any request to access the folder will be
required to verify identity.
WIthout setting on IIS, you can use filters of Web Api.
Authentication filters let you set an authentication scheme for
individual controllers or actions.
[Authorize] // Require authenticated requests.
public class HomeController : ApiController
{
public IHttpActionResult Get() { . . . }
[IdentityBasicAuthentication] // Enable Basic authentication for this action.
public IHttpActionResult Post() { . . . }
}

Related

in Xamarin/App how do I Secure Files on ASP.NET Restful Server in folders from other users and general public

I have an APP using restful server. I want to store PDF's, images, etc. in folders on my server. How can I make the folders private on server, yet allow App to access only certain folders depending on their app access.
I have different users in app and security/tokens established, etc. But if they upload an image for their avatar (and now PDF's), they get stored in folders on the server, and I just display with image source=https://blahblah.com/org1/images/user232.jpg.
How can I make that not accessible to outside (like just going to browser), yet make accessible to app if they have correct login privilege's for that organization/user? And then further extend that logic to more sensative PDF's, and other docs uploaded through app. I didn't want to store in SQL since then harder to use simple image display tools and I already have upload and media managers using folders structures.
I can see how to secure if logging onto server through browser (credentials), but can't see how you connect App with that security level and maintain it for the session.
For future readers. Most of the work was done on the restful (ASP.NET) side. I first tried using authorization/Authentication in web.config and having Allow and deny. This allowed a redirect of a user to a login page; however, it didn't do it if they entered an image exactly correct on website.
Found HTTPHandlers (adding in webconfig ) where I could write code that would be executed once the user entered the specific Image address xyz/abc/image.png. I found this a bit feeling like a hack.
So lastly modified my
routes.MapRoute(
name: "staticFileRoute",
url: "publicstor/{*file}",
defaults: new { controller = "Home", action = "HandleStatic" }
And add a function like this to home controller.
[System.Web.Http.HttpGet]
public ActionResult HandleStatic(string file)
{
if (Session["OrgId"] == null) //todo need to add full security check.
{
return View("Login");
}
else //Either coming from app or coming from web interface
{
string mimeType = MimeInfo.GetMimeType(Path.GetExtension(file));
return File(file, mimeType);
}
}
The final bit is on the Xamarin side to now pass security when getting an image. Since just a simple Xamarin.Forms.Image doesn't have a way to pass login info or tokens/authentication I used
https://forums.xamarin.com/discussion/145575/image-from-url-needing-auth
And established an appwide webclient that logged in generally once forcing my restful to go through security validation, then just accessed the images/documents through out my app from that webclient. So far so good. Hopefully there are no holes.
This gives the gist to a future reader.

How to prevent hitting method in asp.net web api controller with directly typed url in browser?

I have mu backend application in asp.net web api (frontend is angular 8 app)
i have method in controller:
[RoutePrefix("Payment")]
public class PaymentDeadlineController : ApiController
{
DKServiceClient DkService = new DKServiceClient();
SrvPartlyPayment PartlyPayment = new SrvPartlyPayment();
[Route("GetNotified")]
public void GetNotified()
{
DkService.SrvC_CPCheckIsActive();
}
}
How to prevent entering this method GetNotified() when someone opens browser and types http://HostedLocation/Payment/GetNotified in the url?
If you are looking to secure your API from unauthorized access,
You can add [Authorize] attribute in the web api controller and enable Authorization for your API in your startup.cs.
Your front end application can send request to API along with a token issued by your identity provider to API and get response,
while other anonymous users will not have token and hence cannot invoke your method using browser or any other tools like postman.

Get session in ASP boilerplate service layer

I am currently use AspNetBoilerplate to implement my services in service layer...
So I can access session in MVC controller like:
Token token = HttpContext.Session["Token"] as Token;
After login Token session be initiated....
I can access thta everywhere in MVC controllers but in ApplicationServiceBase it is null like:
public class AuditAppService : ApplicationServiceBase, IAuditAppService
{
public GetUserActions_Box GetUserActions()
{
var token = HttpContext.Current.Session.GetToken();
return GetUserActions_Box.Empty;
}
}
HttpContext.Current.Session is null why?
that app services are implemented in separate library which is added in main web application.
I followed the documentation and crossed This, I think AbpSession is not my solution which mean by it we can access some basics info about session that initiated by AbpBoilerPlate authentication system not ours.
use IAbpSession .
you can use claims to add your custom values to the AbpSession.
previously answered here about how to extend AbpSession
Extend ClaimsAbpSession
read AbpSession https://aspnetboilerplate.com/Pages/Documents/Abp-Session

Are all incoming requests handled by AuthorizeAttribute in ASP.NET MVC?

I am developing a ASP.NET MVC 5 website which uses local STS for authentication.
I subclassed the AuthorizeAttribute to customize authentication/authorization process, added MyAuthorizeAttribute to GlobalFilters.
When user came in without authenticated, MyAuthorizeAttribute.OnAuthorize successfully caught it and create a SignInRequest to redirect to STS. That is what I want.
I observed that when user authenticated successfully and STS redirected user back, user's browser POSTed a SAML token embedded in request body to my MVC web application, this is by design, and I expected MyAuthenticateAttribute could catch this request, so I can extract the token from request body, check and validate it, however, MyAuthenticateAttribute.OnAuthorize() function didn't get called this time, it directly went to controller.
So is there anything wrong? Where should i catch and handle the token POSTed from user? Thanks.
You need to decorate your action method with [Authorize] attribute or if you want authorization to happen for all actions in a controller, then set that attribute on the controller itself.
Also take a look at the usage of [AllowAnonymous] at https://www.codeproject.com/Articles/1008731/Insight-of-ASP-NET-MVC-s-Authorize-Attribute
AuthorizeAttribute is both an Attribute and a IAuthorizationFilter. Attributes don't actually do anything, the MVC framework scans for where this attribute is added and registers it as a filter on the fly.
However, rather than decorating controllers or action methods with it, you could add it as a global filter:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new AuthorizationAttribute());
filters.Add(new HandleErrorAttribute());
}
}
By the same token, you can create your own IAuthorizationFilter or subclass AuthorizeAttribute to do whatever you want. If registered globally, it will always run for all actions and then you can use it to do custom authorization of requests globally.

Implementing Authorization in a Self Hosted SignalR Server accessed from Web

I'm looking for some guidance on how to implement authorization security for SignalR on a back end service running in a self-hosted (non-IIS) environment, that is called from a Web application. The backend app is basically a monitor that fires SignalR events back to the HTML based client. This all works fine (amazingly well actually).
However, we need to restrict access to the server for authenticated users from the Web site. So basically if a user is authenticated on the Web site, we need to somehow pick up the crendentials (user name is enough) and validation state in the backend app to decide whether to allow the connection as to avoid unauthorized access.
Can anybody point at some strategies or patterns on how to accomplish this sort of auth forwarding?
I am having similar issues here, as in my web app I use a simple cookie authentication system which uses an AoP style approach to check for any controllers with an attribute, then will get the current context (be it from the static HttpContext.Current or from the target invocation object depending on the type of interceptor) and then verify the cookie exists, it contains right data, then finally verify the token with the db or cache etc.
Anyway this approach can also be used for Signalr, although its a bit more long winded and you are using dependency injection. You would basically wrap the hub calls with the desired attribute, then set up your DI/IoC configuration to intercept these calls, then either get the hub instance within your interceptor and get the cookie (or your custom authentication mechanism) from the request, verify it is all valid or not, and if not then throw a new HttpException("403", "Not authenticated"); which should kick the user out and return back before it even hits your hub method, this way you can put the logic in one place (your interceptor, or a class the interceptor consumes) then just wrap any method that needs to use this authentication using your attribute.
I use Ninject and the interception extension, but most major DI frameworks these days have some form of IoC plugin/extensions, such as Autofac, Windsor, Spring etc.
If you were not happy going down the route of introducing DI and/or AOP to your current project, then maybe you could just create a custom hub instance which contains your authentication logic and then just use that in your hubs, so ok you will still be manually calling some authentication logic from within each hub method you want to protect, but its less code, so something like:
public class AuthorisableHub : Hub
{
private ISomeAuthenticationToken GetSomeAuthenticationTokenFromRequest(Request request) // probably a SignalR specific request object
{
// Get your token from the querystring or cookie etc
}
private bool IsAuthenticationTokenValid(ISomeAuthenticationToken token)
{
// Perform some validation, be it simple or db based and return result
}
protected void PerformUserAuthentication()
{
var token = GetSomeAuthenticationTokenFromRequest(Context.Request);
var isRequestValid = IsAuthenticationTokenValid(token);
if(!isRequestValid)
{ throw new HttpException(403, "<Some forbidden message here>"); }
}
}
public class MyFancyPantsHub : AuthorisableHub
{
public void TellAllClientsSomethingSecret(ISecret secret)
{
PerformUserAuthentication();
// Do stuff with the secret as it should have bombed the user out
// before it reaches here if working correctly
}
}
It is not perfect but would work (I think), also I am sure I once read somewhere that Hubs are newly instantiated for each request, and if this is indeed true, you could possibly just put this logic in your constructor if you want to apply the authentication to every action within the hub.
Hope that helps, or gives you ideas... would be interested in knowing how you did solve it in the end.
SignalR does not provide any additional features for authentication. Instead, it is designed to work with the authentication mechanism of your application.
Hubs
You should do authentication as you normally would and then use the Authorize attribute provided by SignalR to enforce the results of the authentication on the Hubs.
The Authorize attribute can be applied to an entire Hub or particular methods in the Hub. Some examples:
[Authorize] – only authenticated users
[Authorize(Roles = "Admin,Manager")] – only authenticated users in the specified .NET roles
[Authorize(Users = "user1,user2")] – only authenticated users with the specified user names
You can also require all Hubs to require authentication by adding the following method in the Application_Start method:
GlobalHost.HubPipeline.RequireAuthentication();
Persistent Connections
You can use the user object in the request to see if the user is authenticated:
request.User.IsAuthenticated

Resources