How can I get more debugging info about the Symfony2 security system? - security

In general, how can I get useful debugging output about the decisions made by the various components of the Symfony2 security system during request processing? I would love to see things like what firewall and access_control statements were applied and why. What tools are there to make it easier to address the perennial "Why did I get redirected to the login form again" mystery?

You can use Blackfire if you need detailed debug information.
If its not sufficient then you can use WebProfilerBundle it has good debugging information.
If that also not work for you then you can create your own Data Collector Services.
Data Collectors are just like profiler extensions and they can help you to collect different data like routes, debug information or mailer data also. You can customize them according to your need.
Please check the documentation Here
Please check SecurityDebugBundle This will answer your all questions.
Use it carefully, as it requires different permissions.
By Reading its code you will understand how Data Collectors can help you out in debugging.
Hope that will help you.
Here is the DataCollecotr from SecurityDebugBundle:
class FirewallCollector
{
const HAS_RESPONSE = SecurityDebugDataCollector::DENIED;
private $securityContext;
private $container;
public function __construct(
SecurityContextInterface $securityContext,
Container $container
) {
$this->securityContext = $securityContext;
//Container dependency is a bad thing. This is to be refactored to a compiler pass
//where all the firewall providers will be fetched
$this->container = $container;
}
public function collect(Request $request, \Exception $exception)
{
$token = $this->securityContext->getToken();
if (!method_exists($token, 'getProviderKey')) {
return;
}
$providerKey = $token->getProviderKey();
$map = $this->container->get('security.firewall.map.context.' . $providerKey);
$firewallContext = $map->getContext();
$event = new GetResponseEvent(
new SimpleHttpKernel(),
$request,
HttpKernelInterface::MASTER_REQUEST
);
$firewalls = array();
foreach ($firewallContext[0] as $i => $listener) {
$firewalls[$i]= array('class' => get_class($listener), 'result' => SecurityDebugDataCollector::GRANTED);
try {
$listener->handle($event);
} catch (AccessDeniedException $ade) {
$firewalls[$i]['result'] = SecurityDebugDataCollector::DENIED;
break;
}
if ($event->hasResponse()) {
$firewalls[$i]['result'] = self::HAS_RESPONSE;
break;
}
}
return $firewalls;
}
}
This gives alot information on Firewall.
This Bundle Also contains SecurityDebugDataCollector and VotersCollector. So it can give information on all security components.

Related

How to get all assets from an azure media service account

I am trying to get all assets from an azure media service account, Here is my code:
MediaContract mediaService = MediaService.create(MediaConfiguration.configureWithOAuthAuthentication(
mediaServiceUri, oAuthUri, AMSAccountName, AMSAccountKey, scope));
List<AssetInfo> info = mediaService.list(Asset.list());
However, this only gives me 1000 of them, and there are definitely more than that in the account.
In Azure table query, there is a token to be used to get more entries if there are more than 1000 of them.
Does anybody knows how I can get all assets for azure media service?
Thanks,
With Alex's help, i am able to hack the java-sdk the same way as this php implementation
Here are the codes:
List<AssetInfo> allAssets = new ArrayList<>();
int skip = 0;
while (true) {
List<AssetInfo> curAssets = mediaService.list(getAllAssetPage(skip));
if (curAssets.size() > 0) {
allAssets.addAll(curAssets);
if (curAssets.size() == 1000) {
System.out.println(String.format("Got %d assets.", allAssets.size()));
skip += 1000;
} else {
break;
}
} else {
break;
}
}
private static DefaultListOperation<AssetInfo> getAllAssetPage(int skip) {
return new DefaultListOperation<AssetInfo>("Assets",
new GenericType<ListResult<AssetInfo>>() {
}).setSkip(skip);
}
it is the built-in limit due to performance reasons (and REST v2), i believe. I think there is no way to retrieve all of them by one query.
It is possible, however, to use take and skip 1000 by 1000 etc.
But i see that you use MediaContract class, and i could not find it in the .NET repository - i guess it is Java one? I can't comment on that, but i believe the approach should be the same as described in the article (skip/take).
I have found the PHP implementation, maybe will be helpful.
https://msdn.microsoft.com/library/gg309461.aspx#BKMK_skip

Switch vs if else

I use if else for custom menus in Wordpress, to load various location menus based on parent page. The agency I work for is adding countless amounts of cities, and it's getting out of hand. One thing I am trying to do, is come up with a more efficient way to check the items, someone suggested switch, and I just wanted to throw this out there and see what you all think. These are not complete codes, and I know the menus are bad UX, and all that, it's not my call. I just want some input on performance differences. thanks.
Here is an example of switch code:
function is_subpage() {
global $post; // load details about this page
if ( is_page() && $post->post_parent ) { // test to see if the page has a parent
return $post->post_parent; // return the ID of the parent post
} else { // there is no parent so ...
return false; // ... the answer to the question is false
}
}
$selectedMenu = "primary";
$my_page_id = is_subpage();
if(!$my_page_id)
$my_page_id = get_the_ID();
switch ($my_page_id) {
case('489'):
$selectedMenu = 'columbus';
break;
case('6583'):
$selectedMenu = 'cumming';
break;
}
wp_nav_menu( array(
'theme_location' => 'main-menu',
'menu' => $selectedMenu,
'menu_class' => 'clearfix'
));
and here is an example of if else code:
if(is_page( '28' ) || '28' == $post->post_parent) { $locationMenu = 'louisville'; }
'menu' => $locationMenu,
Don't second guess or assume anything about the efficiency of an interpreter or compiler. if else might be better at one scenario and switch at another.
The problem with your code is readability and maintainability and not performance. It is hard to be specific without knowing all details about your needs, but it seems like what you need is to have at each post a custom field which indicates the menu associated with that post, and then the admin can configure them and you will have some more coffee time ;)
This is actually a worse solution in terms of performance, but if you really need the site to be fast then you are going to use a caching plugin which will make the whole php related performance discussion just a waste of time.
From a PHP perspective...
In lieu of having the page id to location table in a database, you could include a structure like this on pages you need it:
$idToLocation = array(
"489" => "columbus",
"6583" => "cumming"
// et cetera
);
Then to get the location:
$id = "489"; // for example
if (!array_key_exists($id, $idToLocation)) {
echo "location for id not found";
die();
}
$location = $idToLocation[$id];

CQRS in data-centric processes

I have got a question related to CQRS in data centric processes. Let me explain it better.
Consider we have a SOAP/JSON/whatever service, which transfers some data to our system during an integration process. It is said that in CQRS every state change must be achieved by the means of commands (or events if Event Sourcing is used).
When it comes to our integrating process we have got a great deal of structured DATA instead of a set of commands/events and I am wondering how to actually process those data.
// Some Façade service
class SomeService
{
$_someService;
public function __construct(SomeService $someService)
{
$this->_someService = $someService;
}
// Magic function to make it all good and
public function process($dto)
{
// if I get it correctly here I need somehow
// convert incoming dto (xml/json/array/etc)
// to a set of commands, i. e
$this->someService->doSomeStuff($dto->someStuffData);
// SomeStuffChangedEvent raised here
$this->someService->doSomeMoreStuff($dtom->someMoreStuffData);
// SomeMoreStuffChangedEvent raised here
}
}
My question is whether my suggestion is suitable in the given case or there may be some better methods to do what I need. Thank you in advance.
Agreed, a service may have a different interface. If you create a rest-api to update employees, you may want to provide an UpdateEmployeeMessage which contains everything that can change. In a CRUD-kind of service, this message would probably mirror the database.
Inside of the service, you can split the message into commands:
public void Update(UpdateEmployeeMessage message)
{
bus.Send(new UpdateName
{
EmployeeId = message.EmployeeId,
First = message.FirstName,
Last = message.LastName,
});
bus.Send(new UpdateAddress
{
EmployeeId = message.EmployeeId,
Street = message.Street,
ZipCode = message.ZipCode,
City = message.City
});
bus.Send(new UpdateContactInfo
{
EmployeeId = message.EmployeeId,
Phone = message.Phone,
Email = message.Email
});
}
Or you could call the aggregate directly:
public void Update(UpdateEmployeeMessage message)
{
var employee = repository.Get<Employee>(message.EmployeeId);
employee.UpdateName(message.FirstName, message.LastName);
employee.UpdateAddress(message.Street, message.ZipCode, message.City);
employee.UpdatePhone(message.Phone);
employee.UpdateEmail(message.Email);
repository.Save(employee);
}

Processing an emaillist async in MVC4

I'm trying to make my MVC4-website check to see if people should be alerted with an email because they haven't done something.
I'm having a hard time figuring out how to approach this. I checked if the shared hosting platform would allow me to activate some sort of cronjob, but this is not available.
So now my idea is to perform this check on each page-request, which already seems suboptimal (because of the overhead). But I thought that with using an async it would not be in the way of people just visiting the site.
I first tried to do this in the Application_BeginRequest method in Global.asax, but then it gets called multiple times per page-request, so that didn't work.
Next I found that I can make a Global Filter which executes on OnResultExecuted, which would seemed promising, but still it's no go.
The problem I get there is that I'm using MVCMailer to send the mails, and when I execute it I get the error: {"Value cannot be null.\r\nParameter name: httpContext"}
This probably means that mailer needs the context.
The code I now have in my global filter is the following:
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
HandleEmptyProfileAlerts();
}
private void HandleEmptyProfileAlerts()
{
new Thread(() =>
{
bool active = false;
new UserMailer().AlertFirst("bla#bla.com").Send();
DB db = new DB();
DateTime CutoffDate = DateTime.Now.AddDays(-5);
var ProfilesToAlert = db.UserProfiles.Where(x => x.CreatedOn < CutoffDate && !x.ProfileActive && x.AlertsSent.Where(y => y.AlertType == "First").Count() == 0).ToList();
foreach (UserProfile up in ProfilesToAlert)
{
if (active)
{
new UserMailer().AlertFirst(up.UserName).Send();
up.AlertsSent.Add(new UserAlert { AlertType = "First", DateSent = DateTime.Now, UserProfileID = up.UserId });
}
else
System.Diagnostics.Debug.WriteLine(up.UserName);
}
db.SaveChanges();
}).Start();
}
So my question is, am I going about this the right way, and if so, how can I make sure that MVCMailer gets the right context?
The usual way to do this kind of thing is to have a single background thread that periodically does the checks you're interested in.
You would start the thread from Application_Start(). It's common to use a database to queue and store work items, although it can also be done in memory if it's better for your app.

Symfony 2.1 - $this->get('security.context')->isGranted('ROLE_ADMIN') returns false even if Profiler says I have that role

I have a Controller action (the Controller has $this->securityContext set to $this->get('security.context') via JMSDiExtraBundle):
$user = $this->securityContext->getToken()->getUser();
$groupRepo = $this->getDoctrine()->getRepository('KekRozsakFrontBundle:Group');
if ($this->securityContext->isGranted('ROLE_ADMIN') === false) {
$myGroups = $groupRepo->findByLeader($user);
} else {
$myGroups = $groupRepo->findAll();
}
When I log in to the dev environment and check the profiler, I can see that I have the ROLE_ADMIN role granted, but I still get the filtered list of Groups.
I have put some debugging code in my Controller, and Symfony's RoleVoter.php. The string representation of the Token in my Controller ($this->securityContext->getToken()) and the one in RoleVoter.php are the same, but when I use $token->getRoles(), I get two different arrays.
My Users and Roles are stored in the database via the User and Role entities. Is this a bug that I found or am I doing something wrong?
Finally got it. A dim idea hit my mind a minute ago. The problem was caused my own RoleHierarchyInterface implementation. My original idea was to copy Symfony's own, but load it from the ORM instead of security.yml. But because of this, I had to totally rewrite the buildRoleMap() function. The diff is as follows:
private function buildRoleMap()
{
$this->map = array();
$roles = $this->roleRepo->findAll();
foreach ($roles as $mainRole) {
$main = $mainRole->getRole();
- $this->map[$main] = array();
+ $this->map[$main] = array($main);
foreach ($mainRole->getInheritedRoles() as $childRole) {
$this->map[$main][] = $childRole->getRole();
// TODO: This is one-level only. Get as deep as possible.
// BEWARE OF RECURSIVE NESTING!
foreach ($childRole->getInheritedRoles() as $grandchildRole) {
$this->map[$main][] = $grandchildRole->getRole();
}
}
}
}
This case - roles are set and are displayed in Symfony's profiler but isGranted returns false - can be happened when the role names does not start with prefix ROLE_.
Bad role name: USER_TYPE_ADMIN
Correct role name: ROLE_USER_TYPE_ADMIN

Resources