I have read many ideas about how to pass parameter in middleware but if there is any possibilities to get full example about that
I believe you are trying to customise the middleware functionality.
Check out this post by Matt Stauffer (if you have not read).
It clearly answers your question. It would get you started.
Passing parameters to middleware
In Laravel API I'm not sure if there is a hasRole() method. But we can create one likewise.
Extending the laravel Auth class with hasRole()
Two tables are needed Users & Roles.
Add this in user model:
public function hasRole($role) {
return Role::where(array('user_id' => Auth::user()->id, 'role' => $role))->get();
}
Remember to include the Role model path on top.
Add this inside the Middleware:
public function handle($request, Closure $next, $role) {
If($this->auth->guest()) {
return redirect()->guest('login');
}
if (Auth::check() && Auth::user()->hasRole($role)) {
return $next($request);
}
}
Hope this is helpful.
Related
I'm new to ASP.NET Core, and I have been trying to look for a way to implement permission-based authorization where a user has to have a certain permission to access a particular action. As I was going through Microsoft Authorization documentation, they explained how to achieve this by using a custom IAuthorizationPolicyProvider which I have understood but not yet tried it out.
But my question is, Is there any problem or is it okay if I use a custom parameterized authorization filter to do the same?
public class HasPermissionAttribute : Attribute, IAuthorizationFilter
{
private readonly string permission;
public HasPermissionAttribute(string permission)
{
this.permission = permission;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var user = context.HttpContext.User;
if (user.HasClaim("Permission", permission))
{
context.Result = new UnauthorizedResult();
}
}
}
And use the filter as seen below
public class HomeController : Controller
{
[HasPermission("User_Edit")
public IActionResult EditUser()
{
var user = HttpContext.User;
return View(user);
}
}
From the code above, what if I add some custom claims of type "Permission" then use them to authorization a user.
Is there any drawback to doing it this way or should I stick to creating a custom IAuthorizationPolicyProvider?
I am a beginner, and I think this way is too easy and that kinda makes me think that it's not really the right way of achieving what I want to achieve. Any feedback will be appreciated. Thanks
The recommend way is to use policy based approach , generate the policies dynamically with a custom AuthorizationPolicyProvider using custom authorization attribute .
From this reply :
We don't want you writing custom authorize attributes. If you need to do that we've done something wrong. Instead you should be writing authorization requirements.
Similar discussion here is also for your reference .
So I need to validate oauth token on every page except for site/login, site/logout, site/error, site/auth. Building off of the advanced template, this would obviously be in the backend.
What would be the proper way of doing this in Yii2?
extending all controllers from some sort of base controller?
bootstrapping a class in config?
custom filter?
behaviours?
Essentially I just need a function to run on every page except the 4 mentioned above.
Yii 2.0 already have 3 authentication methods implemented as filters :
yii\filters\auth\HttpBasicAuth
yii\filters\auth\HttpBearerAuth
yii\filters\auth\QueryParamAuth
Plus yii\filters\auth\CompositeAuth to use more than one at the same time. They are usually attached to each controller within a behavior :
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'authMethods' => [
HttpBasicAuth::className(),
HttpBearerAuth::className(),
QueryParamAuth::className(),
],
];
return $behaviors;
}
And all of them have an $except and $only properties to choose to which actions you are applying them. So you may have something like this in your SiteController :
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
'except' => ['login','logout','error','auth']
];
return $behaviors;
}
And you may have the the same behavior but without the except property in all the other controllers. Or you can make all the other controllers extends a common controller where that authenticator behavior is implemented.
Those filters will use the built-in User class (as set in your config file) which implements the IdentityInterface to authenticate a user. That interface has already a findIdentityByAccessToken() method that you can use to validate a token instead of using findIdentity() to register a logged in user and make it accessible within Yii::$app->user->identity or Yii::$app->user->id.
What I'm trying to explain here is kind of a summary of how Authentication is implemented within the built-in Yii RESTful API framework which may be better explained here :
http://www.yiiframework.com/doc-2.0/guide-rest-authentication.html
And which I consider a good exemple to follow. There is also this tutorial that describes authentication by access token and how it is implemented within the User class. It is about REST but the technique should be the same for a non REST app too as both are using the User class.
I'm using the Repository pattern in a way very close to the one Chris Fidao's used on Implementing Laravel book. Basically I have concrete repository classes that implements its interfaces and gets models injected.
Now I want to take advantage of Laravel's route binding. Since I'm using repositories, I can't bind them to models directly... right? However I didn't get to do this.
I'm using a service provider to bind my concrete repositories to interfaces, like that:
$app->bind('App\Repositories\UserInterface', function ($app) {
return new EloquentUser(new User);
});
How can I bind my routes to repositories interfaces? Seems to be trivial, but I'm a bit lost...
Thank you in advance! :)
You can use a different approach to pass a model to a form without binding a model to a route, for example, assume you have a route which uses UserController and this is the controller:
class UserController extends BaseController {
public function __construct(UserInterface $UserRepo)
{
$this->repo = $UserRepo;
}
public function edit($id)
{
$user = $this->user->find($id);
return View::make('user.edit')->with('user', $user);
}
}
Your form in the user.edit view:
{{ Form::model($user, array('route' => array('user.update', $user->id))) }}
You can use a Repo in your routes the following way. But, do you really need this?
\\the repo is in the Branches folder
use App\Repos\Branches\BranchRepository;
Route::get('branches',function(BranchRepository $branchRepo){
\\using a method of your repo - in this case using getData() method
return $branchRepo->getData();
});
i am very new to mvc
//localhost:51525/api/products/GetPromotionTypes
the controller i have got is as bellow
public IEnumerable<Product> GetAll()
{
return Utility.GetDiscountItems();
}
public Product GetProduct(string Id)
{
return Utility.GetProduct(Id);
}
public String PostBag(Bag bagofItem)
{
return Utility.PostBagDiscountedItem(bagofItem);
}
public List<PromotionType> GetPromotionTypes()
{
return Utility.GetPromotionTypes();
}
when i call from the above uri it pointing to the controller GetProduc() but what i wanted it to call GetPromotionTypes()
what i have done wrong
appreciate all your help
If this is a WebAPI Controller, then you can only have one GET method per controller.
WebAPI was designed to only have 5 calls, GET (one item / list items), POST, PUT and DELETE per entity type. This allows for REST URLs, such as Folders/Get/5, Folders/Get etc.
You should add another API Controller for PromotionType.
Have a run through this tutorial here. http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
You do not have Routing set up properly. I suppose it treats your call as an simple GET request with GetPromotionTypes parameter.
I would like to inject, with full testability, the id of the current logged in user into a creator_id field of a Doctrine_Record class, without using the sfContext singleton. I found a couple of Doctrine behaviours like http://www.symfony-project.org/plugins/sfDoctrineActAsSignablePlugin, but they access the sfContext singleton in a listener or (in another example I found) in the save method of a subclass of Doctrine_Record.
I want to find a single entry point in the symfony controller, where I can inject the current logged in user and keep it till the end of the request.
How do I do?
Hope I have been clear enough.
EDIT:
As #jeremy suggested, I made a custom filter:
class userFilter extends sfFilter
{
public function execute($filterChain)
{
$user = $this->getContext()->getUser();
if ($user->isAuthenticated()) {
$guard = $user->getGuardUser();
Doctrine_Manager::getInstance()->setAttribute('logged_in_user', $guard->getId());
}
// Execute next filter
$filterChain->execute();
}
}
So now my tests and my tasks are sfContext free, I just have to set the proper user Id at some point before starting the interactions with the db:
Doctrine_Manager::getInstance()->setAttribute('logged_in_user', sfConfig::get('default_user'));
Great question! The use of sfContext everywhere is one of the uglier aspects of Symfony 1 and setting it on Doctrine_Manager sounds like a solid idea.
It's probably best to do this either in the configureDoctrine callback that happens in ProjectConfiguration (see below). I'm not 100% a user is present at this point, if it's not, your best bet is a custom filter (reference).
public function configureDoctrine(Doctrine_Manager $manager)
{
$manager->setParam('user_id', sfContext::getInstance()->getUser()->getGuardUser()->getId());
}
Thanks for raising this question. I wrote the http://www.symfony-project.org/plugins/sfAuditablePlugin with this in mind. I basically externalized the method that returns the userId so you can get the userId from session, doctrine parameter or wherever you have it.
Here are the settings to configure the method that returns an array containing user_id and user_name
# Retrieve User Array from custom implementation
# [0] => (int)user_id; [1] => (string)user_name;
getUserArray:
class_name: Utility
static_method_name: getUserAuditArray