Silex security doesn't ask name and password - apache

I am using Silex and apache. I want to disallow access for anonymous users to localhost/admin page. I read docs, docs of SimpleUserProvider and create the following index.php:
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Silex\Provider;
use Symfony\Component\HttpFoundation\Request;
$app = new Silex\Application();
$app->register(new Provider\SecurityServiceProvider());
$app->register(new Provider\SessionServiceProvider());
$app->register(new Provider\TwigServiceProvider(), [
"twig.path" => __DIR__.'/../views'
]);
$app['debug'] = true;
$app['security.firewalls'] = array(
'default' => array(
'pattern' => '^/',
),
'secured' => array(
'pattern' => '^/admin/',
'form' => array('login_path' => '/login', 'check_path' => '/login_check'),
'users' => array(
'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
'daria' => array('ROLE_USER', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
),
),
);
$app['security.access_rules'] = array(
array('^/admin', 'ROLE_ADMIN', 'https'),
array('^.*$', 'ROLE_USER'),
);
$app -> boot();
$app->get('/', function () {
return 'Hello from Silex container.';
});
$app->get('/admin/', function() {
return "Admin page";
});
$app->get('/login', function(Request $request) use ($app) {
return "Login page";
});
$app->get('/logout/', function() {
return "Logout page";
});
$app->get('/admin/login_check/', function() {
return "Admin login check page";
});
$app->run();
As Symfony 2 docs says, if I request to localhost/admin, I should see input fields for pass and login in alert.
So when I go to 'localhost' all are right, I see correct message. But when I go to 'localhost/admin' I expect that browser will ask with alert my login and password. But it doesn't happens, I get 'ERR_CONNECTION_REFUSED Site localhost disallow connection'. In apache log I have 301 http code. Is it normal behavior that browser doesn't ask login/password with alert? If yes, what should I add to code to change that behavior?
P.S. I know that hardcoded login and password are terrible, but I am just started Silex and it doesn't matter.

I think that you get ERR_CONNECTION_REFUSED error because of redirect to https. Try to remove this redirect by changing array('^/admin', 'ROLE_ADMIN', 'https'), to array('^/admin', 'ROLE_ADMIN'),.
Remove default section from firewalls. This section is first, catches all requests and doesn't require authorization.
If you want standard alert with user/password prompt, specify http entry point instead of form.
$app['security.firewalls'] = array(
'secured' => array(
'pattern' => '^/admin/',
'http' => array(),
'users' => array(
'admin' => array('ROLE_ADMIN', '...'),
'daria' => array('ROLE_USER', '...'),
),
),
);

Related

How to set cookie before test in Laravel?

I need to test a specific behaviour based on the presence of a cookie, how do I set a cookie before sending the request (or visiting the page) ? For the moment the following fails, it behaves likes nothing was set.
$this->actingAs($user)
->withSession(['user' => $user, 'profile' => $profile]) ;
#setcookie( 'locale_lc', "fr", time() + 60 * 60 * 24 * 900, '/', "domain.com", true, true) ;
$this->visit('/profile') ;
Or
$cookie = ['locale_lc' => Crypt::encrypt('fr')] ;
$this->actingAs($user)
->withSession(['user' => $user, 'profile' => $profile])
->makeRequest('GET', '/profile', [], $cookie) ;
The problem was in the setting and reading of cookies. Neither #setcookie nor $_COOKIE will work from a testing context. The method makeRequest with a cookie array is the right one.
However !
The reading script (controller, middleware) must be using Laravel's $request->cookie() method and not directly try to access it with $_COOKIE. In my case the cookie needs to be read by another app on our domain so I also had to disable the encryption for that specific cookie, which can be done in EncryptCookies.php
EncryptCookies
<?php
protected $except = [
'locale_lc'
];
Test
<?php
$cookie = ['locale_lc' => 'fr'] ;
$this->actingAs($user)
->withSession(['user' => $user, 'profile' => $profile])
->makeRequest('GET', '/profile', [], $cookie) ;
Middleware
<?php
public function handle($request, Closure $next){
if($request->cookie('locale_lc')){...}
}

Secured authentification for users Laravel 4

I'm working on a new Laravel 4 project and i would like to secure the authentication route over the SSL protocol and honestly i searched for 2 days with no luck and i have no idea how to do that.
That's my routes.php file:
Route::group(array('before' => 'guest'), function(){
/*==========================
| csrf PROTECTION
*///========================
Route::group(array('before' => 'csrf'), function(){
/*==========================
| Post Sign-in
*///========================
Route::post('/account/sign-in', array(
'as' => 'account-sign-in-post',
'uses' => 'AccountController#postSignIn'
));
});
/*==========================
| Get Sign-in
*///========================
Route::get('/account/sign-in', array(
'as' => 'account-sign-in',
'uses' => 'AccountController#getSignIn'
));
});
i would like to know if is that even possible using wamp, or it can be only done using a real host server, any help would be appreciated, and sorry for my bad English.
You can force routes to serve using https. For example:
Route::get('account/sign-in', array('https', function()
{
return 'Must be over HTTPS';
}));
ref: http://laravel.com/docs/routing

CakePHP Auth->login not generating query for request data

I have the Auth component working perfectly for an application running Cake 2.4.1, and I need to copy it to another application that is also running Cake 2.4.1. I copied over everything I could think of that has to do with Auth stuff, but it just does not work in the second application. It refuses to log me in. The call to $this->Auth->login() fails even though it gets exactly the same data as the application that works.
Both applications are using exactly the same database and user login.
Both applications get exactly the same request data in the POST request.
First of all, here is my setup.
In AppController.php:
public $uses = array ('User');
public $components = array ( 'Session',
'CPRACL.CPRACL' => array (),
'Auth' => array (
// 'loginAction' => array ('controller' => 'users', 'action' => 'login'),
// 'logoutRedirect' => '/users/login',
// 'loginRedirect' => '/',
'authenticate' => array (
'Form' => array (
'fields' => array ('username' => 'email_address'),
'scope' => array ('User.active' => 1)
)
),
'authorize' => array ('Controller'),
// 'unauthorizedRedirect' => '/' // when going to a page the user is not authorized to go to
)
);
The commented out lines use the defaults, but they are included for reference to their default values. This is exactly the same in both applications. CPRACL is a plugin component that I am using instead of Cake's ACL component, but it fails long before it gets to any of that.
Also in AppController.php:
public function beforeFilter ()
{
$login_user = $this->User->find ('first', array ('conditions' => array ('id' => $this->Auth->user ('id'))));
if (!empty ($login_user))
$this->set ('login_user', $login_user ['User']);
}
public function isAuthorized ($user = null)
{
// This never gets called in the application that does not work, but it does get called in the one that works.
}
In both applications, it sets up the Auth component as defined in AppController.php, then it calls beforeFilter to check to see if the user is already logged in. This is a convenience so that when they get redirected to a different page, the application can display the username of the user who is logged in. It works fine and I don't think it is causing any problems.
The next thing that happens is it calls UsersController::login()
public function login ()
{
$redirect_url = $this->Auth->redirectUrl ();
if ($this->Auth->loggedIn ())
return $this->redirect ($redirect_url);
//die (print_r ($this->request->data, true));
if ($this->request->is ('post'))
{
//die (Debugger::dump ($this->Auth));
if ($this->Auth->login ())
return $this->redirect ($redirect_url);
else
return $this->redirect ($this->Auth->loginAction);
}
}
I used the two commented out lines to compare what is happening between the two applications. The two applications get exactly the same data in the post. For the dump of the Auth object, here is what I get:
object(AuthComponent) {
components => array(
(int) 0 => 'Session',
(int) 1 => 'RequestHandler'
)
authenticate => array(
'Form' => array(
[maximum depth reached]
)
)
authorize => array(
(int) 0 => 'Controller'
)
ajaxLogin => null
flash => array(
'element' => 'default',
'key' => 'auth',
'params' => array([maximum depth reached])
)
loginAction => array(
'controller' => 'users',
'action' => 'login',
'plugin' => null
)
loginRedirect => null
logoutRedirect => array(
'controller' => 'users',
'action' => 'login',
'plugin' => null
)
authError => 'You are not authorized to access that location.'
unauthorizedRedirect => true
allowedActions => array(
(int) 0 => 'register',
(int) 1 => 'login',
(int) 2 => 'logout'
)
request => object(CakeRequest) {}
response => object(CakeResponse) {}
settings => array(
'authenticate' => array(
[maximum depth reached]
),
'authorize' => array(
[maximum depth reached]
)
)
Session => object(SessionComponent) {}
[protected] _authenticateObjects => array()
[protected] _authorizeObjects => array()
[protected] _user => array()
[protected] _methods => array(
(int) 0 => 'index',
(int) 1 => 'view',
(int) 2 => 'add',
(int) 3 => 'register',
(int) 4 => 'login',
(int) 5 => 'logout',
(int) 6 => 'toggleactive',
(int) 7 => 'changePassword',
(int) 8 => 'passwordHash',
(int) 10 => 'edit_pwd',
(int) 11 => 'edit_your_pwd',
(int) 12 => 'isAuthorized'
)
[protected] _Collection => object(ComponentCollection) {}
[protected] _componentMap => array(
'Session' => array(
[maximum depth reached]
),
'RequestHandler' => array(
[maximum depth reached]
)
)
}
That is what both applications return from the Auth object dump when I send the login request. It says the user is not authorized to access that location, but I think that is because it hasn't actually logged the user in yet, so I don't think the dump of that Auth object is of much value, but I included it here anyway.
But here is the most important part because it is the only thing that is obviously different between the two applications. When I perform the login on the working application, it logs me in successfully and my layout (which displays the most recent query) shows this query. Notice the id field. The id field is correct in the query and it works.
SELECT `User`.`id`, `User`.`user_id`, `User`.`email_address`, `User`.`first_name`, `User`.`last_name`, `User`.`password`, `User`.`active`, `User`.`created`, `User`.`modified` FROM `brian_cake_test`.`users` AS `User` WHERE `id` = '529f9a8c-3460-46a2-a97c-6a6242a26b88' LIMIT 1
But when I do exactly the same thing for the application that does not work, everything happens exactly the same way except that it redirects me back to the login page, which it should do if it fails to login, and it displays this query in my layout.
SELECT `User`.`id`, `User`.`user_id`, `User`.`email_address`, `User`.`first_name`, `User`.`last_name`, `User`.`password`, `User`.`active`, `User`.`created`, `User`.`modified` FROM `brian_cake_test`.`users` AS `User` WHERE `id` IS NULL LIMIT 1
Notice how the id is NULL in the second query. I have no idea why this is happening.
My User.php model is just an empty class, exactly the same in both application, but one works perfectly and the other does not.
<?php
App::uses ('AppModel', 'Model');
class User extends AppModel
{
public $name = 'User';
}
I have racked my brain trying to figure out what is different between these two applications, and I can't think of anything, and nothing I try will make it work. I don't want to post hundreds of lines of code when I know that 99% of it has nothing to do with this problem, but I have no idea why it works in one but not the other. I will gladly post more information if you think you might know what the problem is. Any help would be much appreciated. This is very important to me.
Actually if its exactly the same code and DB it shouldn't be a reason not to work.
Have you tried clearing the cache folders? Those files sometimes mess up the app.

$facebook->getSignedRequest(); return the correct value in iframe while return null on my server side

i am building a fan gate for my site to give out some coupon.
here is my code:
<?php
require_once 'facebook.php';
$app_id = "xxxxxxxxxxxxxxx";
$app_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => true
));
print_r($_REQUEST);
$signed_request = $facebook->getSignedRequest();
echo "<pre>";
print_r($facebook->getSignedRequest());
echo "</pre>";
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
$like_status = $signed_request["page"]["liked"];
print_r($facebook);
?>
I find that the return value of $facebook->getSignedRequest(); is different when i am visiting my apps via apps.facebook.com/xxxxxxxxxxxxxxxxxxxxxx/ and when i am visiting www.coupon.mysite.com/facebook/index.php
via apps.facebook.com/xxxxxxxxxxxxxxxxxxxxxx/:
Facebook Object ( [appId:protected] => 15255288xxxxxxxx [appSecret:protected] => XXXXXXXXXXXXXXXXXXXX[user:protected] => [signedRequest:protected] => Array ( [algorithm] => HMAC-SHA256 [issued_at] => xxxxxxxxxxxxx[user] => Array ( [country] => hk [locale] => en_US [age] => Array ( [min] => 21 ) ) ) [state:protected] => [accessToken:protected] => [fileUploadSupport:protected] => )
via www.coupon.mysite.com/facebook/index.php:
Facebook Object ( [appId:protected] => xxxxxxxxxxxxxxxxxxx[appSecret:protected] => xxxxxxxxxxxxxxxxxx[user:protected] => [signedRequest:protected] => [state:protected] => [accessToken:protected] => [fileUploadSupport:protected] => )
so the fan gate wont work because $facebook->getSignedRequest(); always return null in my server side. I have do the searching for this problem for some days already and still dont understand what is the problem.
Any help is very much appreciated.
^ ... continue from the comments:
First of all, if you do this, your users will hate you; secondly, that plugin is bit of a scam - all it does is uses cookies to store if user has liked a page - but if you delete your cookies, you will be locked out of the content because you won't be able to like the page again. Furthermore, it won't work without Javascript.
All the plugin does is it hooks into the "like" action when user clicks on the like button via
FB.Event.subscribe('edge.create', function(href, response){});
facebook graph api determine if user likes url

Cakephp 2.0 Auth doesn't redirect to users/login

I have some code in AppControler::beforeFilter()
$this->Auth->authorize = array('Actions' => array('actionPath' => 'controllers'));
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->logoutRedirect = array('controller' => 'users', 'action' => 'login');
But the Auth does not redirect me to the users/login when I'm trying to load nonpublic action in browser. Instead it redirects me to the '/'. What I'm doing wrong?
It's probably because you have not granted permissions to the Login action in the users controller. Add this to the top of the users controller:
function beforeFilter(){
parent::beforeFilter();
$this->Auth->allow('login');
}
As a side note, the loginAction already defaults to /users/login. The same goes for the logoutRedirect. Try removing both as they are not really needed since you are already wanting it to go to the default location.
UPDATE
Have you included the component in the top of the AppController?
public $components = array('Auth');
The other thing to confirm is that you are not already logged in. If you are already logged in but have not granted permission to a specific action within a controller for logged in users, it can redirect as well.