asp.net mvc3 how to pass ID variable but without in browser - linq

I was wondering how can I pass my primary-key int ID myid into a .tolist method that uses a for each loop
VIEW
#foreach (var item in Model)
{
#Html.ActionLink("View", "detail", new { id = item.myid})
#Html.ActionLink("Add Pictures", "pictures")
}
the .tolist controller
[Authorize]
public ActionResult mylist(list listings)
{
var showlist = (from s in db.list where getid == s.RegistrationID select s).ToList();
return View(showlist.ToList());
}
As you can see from above i do have the [authorize] notation on mylist which is were the foreach statement is on so people are logged on already. My question is were can I put the int myid in the #Html.ActionLink("Add Pictures", "pictures") ?? I do not want to have it in the Browser since then users can easily put in different numbers and view other peoples pictures .

You should be passing the id in the url
#Html.ActionLink("Add Pictures", "pictures",new { #id=item.ID})
And in your pictures action method, you should check whether the current User is a logged (Authentication) in user and he has proper permission to add picture (Authorization).
public ActionResult pictures(int id)
{
//TO DO : Check the user has sufficient permission to add pictures.
// The implementation of this checking is completely up to you.
// If not authorized redirect to a view to show the "Not authorized" message
}

Can't you just prevent people from looking at other people's pictures by checking if their user id matches the picture's owner's id?
You have to pass the id to the user, you can't avoid it.

That's not where you stop this kind of "hacking". In your controller or somewhere else, you do a check if the current authenticated user owns that photo and redirect him to a page that says "no picture found" - or something similar.

Related

ASP.NET Core 2.2 - Action Filter db Query Question

I have users in our app, who are mapped to companies. When a user logs in and starts to make requests I want a way to validate if that user is currently mapped to the company for access to company resources.
The idea I had was to create a whole controller just to manage all of this, but someone mentioned ActionFilters as a much better and cleaner option, I have to agree after looking at it.
The idea is to have the controller setup as:
controller - action - CompanyId - ReportId
So any request to root the system would just look up if there are any companies mapped to that logged in user.
But if the request included CompanyId then they'd go to that company's “portal” account page. It's really any request that includes CompanyId where I want the actionFilter to make a determination on if that user is allowed access.
Request comes in...
There is a CompanyId in the request!
ActionFilter:
Look up in db for all users assigned to that CompanyId. Is current user within that list? No? = kick'em out.
I tried to type in a code example, but the system told me to manually indent each line by 4 spaces, I was doing it from memory anyways so no idea how helpful it would have been anyways.
You could get your action parameters in your action filter and then get your database via HttpContext.RequestServices.GetRequiredService<ApplicationDbContext>().Refer to here.
public class TestActionFilter:Attribute,IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
//If companyId is action parameter
var companyId= context.ActionArguments["companyId"].ToString();
//If companyId1 is query string
var companyId1= context.HttpContext.Request.Query["companyId1"].ToString();
//If companyId2 is in request header
var companyId2= context.HttpContext.Request.Headers["companyId2"].ToString();
//get your dbcontext
var db = context.HttpContext.RequestServices.GetRequiredService<ApplicationDbContext>();
//EF core logic
//...
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
You could use it on action directly using [TestActionFilter] attribute or set as global filter
services.AddMvc(options =>
{
options.Filters.Add(new TestActionFilter()); // an instance
});

how to restrict user from accessing another user's pages by inputing id in url laravel

I have a web app i'm working on.Users can create patients, which have a unique id. Problem I have is that when another user logs in, he can easily access patients not assigned to him by simply inputing their id in the url. Please how do i solve this? Heres a sample of my route for the
user to view his patient:
Route::get('patients/{patient}/view', 'Portal\PatientController#viewPatient');
and in the Patientcontroller:
public function viewPatient($patient){
$patient = Patient::where('id', $patient)->first();
return view ('portal.patient',compact('patient'));
}
Please what am I doing wrong?
You can use policies for that:
Policies are classes that organize authorization logic around a particular model or resource. For example, if your application is a blog, you may have a Post model and a corresponding PostPolicy to authorize user actions such as creating or updating posts.
Or gates:
Gates are Closures that determine if a user is authorized to perform a given action
I'd use policies, but you also can manually check if a user can view a page with something like:
if (auth()->id() !== $patient) {
return redirect('/')->with('message', 'You can not view this page');
}
You could also keep GET to access to this page without inputing the id. For example, if you want to obtain patients only from the current user logged in :
web.php :
Route::get('patients/view', 'Portal\PatientController#viewPatient');
Patientcontroller :
public function viewPatient(){
$id = auth()->id();
$patient = Patient::where('id', $id)->first();
return view ('portal.patient',compact('patient'));
}
Keep in mind that this will work only with an authenticated user.
If your database table structure is like this
Patients
--------
id //Unique ID of Patient
user_id //User that created
patient
Then you can do the check in controller like.
public function viewPatient($patient)
{
$patient_check = Patient::where('id', $patient)->where('user_id','=',Auth::user()->id)->first();
if($patient_check == null || count($patient_check) == 0)
{
return "You cannot view this patient";
}
else
{
return view ('portal.patient',compact('patient'));
}
}
This is simple and yet does the work.

Redirecting to a page if session object expires or user did not login to the application

This is a mvc application
I have the links below on my master page
Link1 Link2 Link3 signout signIn
I have a userprofile object that is populated
when authentication is done.
When the session object for the user expires
and I click on the links, I get the yellow page(error page).
I will prefer a situation where when you click on the
links and the session object is expired, you get
redirected to the signin page.
Soln A: I could solve this problem by writing a method
which test for null value of the userprofile object then
make a call to this method on the click on every link.
I dont want this approach because in the future if there
are new controllers, i will need to care for them.
Do you have any idea how I can solve this problem?
I would have a Base Controller than all of your other controllers inherit from. Within this I would have a
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (SessionManager.Instance() == null)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{ "Controller", "BaseController" },
{ "Action", "LogOn" }
});
}
base.OnActionExecuting(filterContext);
}
The OnAction Executing will be hit before any method in any of your controllers - this way you can check your session is valid or your user is valid or whatever and handle the redirect to the view you want if that is not the case. If you do a Google search for Filters Actions MVC you will find out much more info.

Avoiding unauthorized access to a page by changing the URL query parameter in mvc3

I'm new in mvc and I have a question: If I have Index page (page with list of some object this is url http://localhost:6384/admin/) and I have actionlink button on which when user clicks he gets details of that object this is url http://localhost:6384/Admin/Apartman/details/1.
ID of obejct is 1, but if user change value 1 to some other value he will get some other object which maybe he shouldn't be able to see it.
What can I do to protect application?
The way i do it is simply checking whether the user has access to that object.
public ActionResult EditProfile(int id)
{
ApartmentViewModel objVM=MyService.GetApartment(id);
if(objVM.CreatedById==id)
{
return View(objVM);
}
else
{
return View("UnAuthorized");
}
}

MVC3 - RedirectToAction from Edit page back to Details page with parameter

I have a master detail scenario going from a list of categories to ingredients.
In the Edit ActionResult I have:
if (ModelState.IsValid){
dc.Entry(mainingredient).State = EntityState.Modified;
dc.SaveChanges();
int ID = ?????
return RedirectToAction("Details", new { id = ID});
}
...
I am basically trying to go back to the page I came from.
For example... from /Ingredient/Edit/2 back to Ingredient/Details/2
To make this question clearer:
how do I pass an id from the edit get to edit httppost controller so that I can redirect the user back to the details page again passing the id after they make an update?
You could pass a url query string parameter to the Edit action when invoking it. This way you will be able to redirect to:
public ActionResult Edit(string returnUrl)
{
...
return Redirect(url);
}
or if you already know the controller and action:
return RedirectToAction("Details", new { id = ID });
will be sufficient. The ID you want to redirect back could be passed as action argument.

Resources