TYPO3: Custom AuthService reveals in InvalidControllerNameException - php

In TYPO3 11 LTS I've created a custom FE extension which generates a custom login process. For that I've provided an auth Service with 2 subtypes in ext_localconf.php
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addService(
// Extension Key
'mylogin',
// Service type
'auth',
// Service key
'tx_mylogin_login_process_data',
// Info
array(
'subtype' => 'processLoginDataFE,authUserFE',
'available' => true,
'title' => 'Mylogin Authentication',
'description' => 'Services for my login',
'priority' => 85,
'quality' => 85,
'os' => '',
'exec' => '',
'className' => MyLoginAuthenticatorService::class
)
);
MyLoginAuthenticatorService extends TYPO3\CMS\Core\Authentication\AuthenticationService.
Inside MyLoginAuthenticatorService::processLoginData(array &$loginData, $passwordTransmissionStrategy) I check for certain credentials and overwrite the $loginData with the username found by a login_key.
Inside MyLoginAuthenticatorService::authUser(array $user) I get the right/expected fe user array (like in the normal fe_login process). In here I check for a certain circumstance and return an integer 200.
Doing that with some debug I can confirm that I am reaching the point in code with the return 200; and as mentioned above having a filled array with user credentials.
In my extension I use the following Fluid form:
<f:form method="post" action="customlogin" fieldNamePrefix="">
<f:form.hidden name="user" value="{login_key}" />
<f:form.hidden name="pass" value="" />
<f:form.hidden name="logintype" value="login" />
<f:form.hidden name="pid" value="{secure_pid}" />
<f:form.button type="submit">Login</f:form.button>
</f:form>
Now the problem: Without the registered service I can access the customloginAction in my controller. Putting back the service registration after the return 200; my frontend returns:
#1313855173 TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException
The controller "Mycontrollername" is not allowed by plugin "Myloginplugin".
Please check for TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin()
in your ext_localconf.php.
The plugin is the same as the form action and the resulting action is placed in and as mentioned above it all works without the services.
So what is wrong? Is using the auth services even the right way? What do I miss? Is returning 200 in authUserFE enough to trigger all stuff TYPO3 has to do to provide a logged in user?
Edit:
I've found out that going with a <form action="/" ...> the whole solution works perfectly. That form is on the subpage /login. If I do the action="/login" the mentioned InvalidControllerNameException pops up again.
Do you know why that could happen?

you are using <f:form> here which is there for creating extbase forms
it interactis with <f:form...> elements and builds a complex context. in your case you need plain variables so i would sugget just render a regular html form using <form> (no fulid namespace) and regular html elements.

Got it.
It was a deep dive into code / understand what you use problem. Inside my custom AuthenticationService functions I used some functionality right from the ActionController of my custom auth extension.
This causes TYPO3 to build an additional request with no context resulting in the error above. After removing the ActionController stuff from the service context everything works like charm. Yes even with that fluid form:
<f:form method="post" action="customlogin" fieldNamePrefix="">
<f:form.hidden name="user" value="{login_key}" />
<f:form.hidden name="pass" value="" />
<f:form.hidden name="logintype" value="login" />
<f:form.hidden name="pid" value="{secure_pid}" />
<f:form.button type="submit">Login</f:form.button>
</f:form>

Related

Url and Form security in Laravel 5.1

What's the Problem?
Primary Key is present in Url so the data for other records can be seen easily by easily changing the Url.
Rendered html has hidden field present. Anybody can easily change other records based upon this Hidden Field.
When I edit the page. My Url looks like below.
http://localhost/Category/3
and Below is the rendered Html
<form method="POST" action="http://localhost/UpdateCategory" accept-charset="UTF-8">
<input name="_token" type="hidden" value="AmAXKmqtct6VOFbAVJhKLswEtds4VwHWjgu3w5Q8">
<input name="CategoryID" type="hidden" value="3">
<input required="required" name="Category" type="text">
<input class="btn btn-success" type="submit" value="Update">
</form>
Please suggest some Url and Form security in Laravel 5.1
There are many worksaround which shall by handled by us to avoid such incidents.
Fix 1 :
If you don't want to reach the user's by just changing the url
(i.e., Directly passing the id in url )
You shall filter the requests by
if($_SERVER['HTTP_REFERER']!='')
{
}
else
{
exit;
}
You shall have this in your Middleware or even in your view if you wish
Fix 2 : Never worry about the _token that is visible when you see form source
It is just the token that is generated by laravel app which is to identify whether the request is from authenticated source or not.
If you edit the token and pass the form you will surely get CSRF Token Mismatch Exception
Infact this is one of the great feature of Laravel.
Interesting Point : You can also find something in the headers of the browser ;)
Happy using Laravel ;)

Laravel Form POST redirect failure

I'm having a very frustrating (super-newbie) experience with Laravel 5.1.
Sure there must be something that I'm missing, but unfortunately I couldn't find anything on Laravel docs.
The problem is this (and I believe is even relatively simple): while all GET routes are working, the routes in POST are 'rerouting' me to the wrong place.
For instance, assuming that the controller is this:
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use View;
class PagesController extends BaseController {
public function hello(){
return view('hello');
}
public function register(){
//Registration rules
$inputData=array(
'name' => \Input::get('name'),
'email' =>\Input::get('email'),
'password' => bcrypt(\Input::get('password')),
);
createUser($inputData);
return view('stat');
}
private function createUser($inputData){
return User::create($inputData);
}
}
and given the route:
Route::get('/','PagesController#hello');
this one redirects me correctly to the view specified in the controller,at the method indicated.
A POST operation cannot be successfully performed, since
Route::post('/','PagesController#register');
with the form having:
<form action="/" method="post">
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
<label for="name">User Name</label><br/>
<input type="text" name="name" id="name"/><br/>
<label for="name">E-mail</label><br/>
<input type="text" name="email" id="email"/><br/>
<label for="password">password</label><br/>
<input type="password" name="password" id="password"/><br/>
<input type="submit" value="auth!"/>
</form>
results in redirecting me to xampp home page.
For example, the "main registration page" is at this url:
http://localhost:8080/laravel/project1/public/
(GET OK)
and when I click on the submit button, I'm sent to
http://localhost:8080/
Just few more indicators for you to try and help me (I'm genuinely stuck):
1) I didn't use a VirtualHost (searched on the web, but had always no luck in configuring apache properly...good luck I've got xampp)
2) The page "hello" has a link that I used as a test:
Link
and it redirects me correctly to the sought-after
http://localhost:8080/laravel/project1/public/stat
3)In the POST method, I've used a dd($inputData) to see what was going wrong, and as a result I had...nothing. Not a blank page,just always the localhost page. This led me to think that somehow the controller method isn't called, since no dd(---) result got in page.
Hope someone can help.
Many thanks
Your domain is http://localhost:8080 , so when you set action to '/' , it goes to root. It`s not good practice , but your solution is to change :
<form action="/laravel/project1/public/" method="post">
I`d create a virtual host for the project in apache , so document root would be /laravel/project1/public/ .
you are posting your form to the root / that is why you are being routed to xampp page. To solve this problem, change your form action to this
<form action="/post/my/form" method="post">
in your routes
Route::post('/post/my/form','PagesController#register');

Where is the query in wp-login.php WORDPRESS

I am making a loginform in WORDPRESS and i want to have a validation on it, so i tried to look at the wp-login.php to see how they validate things. But i did not find what i am looking for. I would like to know how they validate things or what input do they need to validate things. I tried to search the wordpress forums all i can find is plugin, plugin and more plugin. I dont want a plugin. I want to hardcode it. So please help me.
I want to know where you can find the part that searches for the users username and password.
Or if not , know what is needed for a successful login. example username or password or others.
by the way here is the wp-login.php. THanks
Indeed the auth logic is not located in wp-login.php.
Wordpress relies a lot on hooks (actions and filters). For authentication, this article explain some of the process in wordpress 2.8+. AFAIK this is still the same in 3.x.
Authentication process is based on the authenticate filter. Two hooks are added in the filter queue :
wp_authenticate_username_password() (priority 20) in wp-includes/user.php (line 68)
wp_authenticate_cookie() (priority 30) in wp-includes/user.php (line 117)
See the article for more details.
I encourage you not to hack the core directly but add some hooks on this filter with higher priorities.
Start looking on line 535:
case 'login' :
default:
$secure_cookie = '';
$interim_login = isset($_REQUEST['interim-login']);
That appears to be the login function. At line 630 you get what appears to be the html for the login form:
<form name="loginform" id="loginform" action="<?php echo esc_url( site_url( 'wp-login.php', 'login_post' ) ); ?>" method="post">
<p>
<label for="user_login"><?php _e('Username') ?><br />
<input type="text" name="log" id="user_login" class="input" value="<?php echo esc_attr($user_login); ?>" size="20" tabindex="10" /></label>
</p>
Make your edits and see if that works.

Automatically log in on another website at the click of a button - cURL or Javascript?

I would like to make a button on my website that automatically logs me in on another website. I recon I can use either Javascript/jQuery or PHP/cURL to do this.
Which is the best way to go?
You may use either remote javascript or iFrame. Find more details here: http://kuza55.blogspot.com/2007/06/building-secure-single-sign-on-systems.html
Also checkout google's approach named SAML: http://code.google.com/googleapps/domain/sso/saml_reference_implementation.html
It depends what the website is. JavaScript and jQuery alone cannot be used due to the cross-domain policy. You could perhaps use a combination of cURL and AJAX to achieve something similar.
I think you might need to provide a little more information about the site, and exactly why you'd want to do this...
I'm not sure if this is exactly what you're looking for, but one thing I have done in the past is to mimic the login form on the site you want to log in to.
For example lets say you want to log in to 'example.com'. In the source code for the login page of 'example.com' you will find the html code for the login form.
Example
<form name="blabla" action="action.php" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="sumbit" value="Login" />
</form>
Create a form on your site similar to the one you find in 'example.com'. If you want you can even hide the fields, include values to make it a one button login. The trick is making sure that the action has the actual url. For example if the form says 'action.php' for 'example.com' you would put 'http://example.com/action.php'
Example
<form name="blabla" action="http://example.com/action.php" method="post">
<input type="hidden" name="username" value="testuser" />
<input type="hidden" name="password" value="testpass" />
<input type="sumbit" value="Login" />
<form>
This will log you in to the site in most cases. If you don't want to leave your own site you can set a 'target' for the form to an iframe or something.

Symfony sfDoctrineGuard plugin sfGuardUser module

When using sfDoctrineGuard plugin, it automatically generates the backend administration functionality where I can edit users of the system and assign them permissions.
So I visit http://.../backend_dev.php/sf_guard_user/:id/edit where I am presented with the user's information including the available permissions to select.
By default the permissions are shown as a multiple select box, HTML follows:
<select name="sf_guard_user[permissions_list][]" multiple="multiple" id="sf_guard_user_permissions_list">
<option value="1">Permission1</option>
<option value="2">Permission2</option>
<option value="3">Permission3</option>
<option value="4">Permission4</option>
</select>
What I would prefer is a list of checkboxes. So I searched around and found that if I add the option "expanded" set to true to the following code:
'permissions_list' => new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => 'sfGuardPermission', 'expanded' => true,)),
The code is part of this file: lib/form/doctrine/sfDoctrineGuardPlugin/base/BasesfGuardUserForm.class.php. I don't think I should've edited this file (potential for changes to be overwritten should sfDoctrineGuard ever be re-installed) but couldn't think of another way to make it work.
The generated HTML is as follows:
<ul class="checkbox_list">
<li><input name="sf_guard_user[permissions_list][]" type="checkbox" value="1" id="sf_guard_user_permissions_list_1" /> <label for="sf_guard_user_permissions_list_1">Permission1</label></li>
<li><input name="sf_guard_user[permissions_list][]" type="checkbox" value="2" id="sf_guard_user_permissions_list_2" /> <label for="sf_guard_user_permissions_list_2">Permission2</label></li>
<li><input name="sf_guard_user[permissions_list][]" type="checkbox" value="3" id="sf_guard_user_permissions_list_3" /> <label for="sf_guard_user_permissions_list_3">Permission3</label></li>
<li><input name="sf_guard_user[permissions_list][]" type="checkbox" value="4" id="sf_guard_user_permissions_list_4" /> <label for="sf_guard_user_permissions_list_4">Permission4</label></li>
</ul>
What I need to do now is split up the permissions based on their prefix. For example if I had permissions named user_action1, user_action2, file_action1, file_action2, they would display like:
User
checkbox (custom label) Action One
checkbox Action Two
File
checkbox (custom label) Action One
checkbox Action Two
but have no idea where to start with this. It would be easy if there was a template to edit but since I'm dealing with the Forms framework it is my understanding that the templates are generated on the fly - I can see them in my symonfy cache folder.
How would I go about this?
I started writing my own sfWidgetFormDoctrineChoicePermission class that extends the same class as sfWidgetFormDoctrineChoice but am struggling to edit the rendering functions correctly for the desired output. Is this the correct way to go about this work?
I also need to integrate my sfGuardUserProfile model into the edit user page (same as above), I read somwhere that editing the generator.yml file for the sfGuardUser plugin module and simply adding the field names from the sfGuardUserProfile table would make it work, but sadly it doesn't.
First of all don't ever edit base classes. The one you are wanting to edit is:
lib/form/doctrine/sfDoctrineGuardPlugin/sfGuardUserForm.class.php
From here you can override the default widget by calling:
$this->setWidget('permissions_list', new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => 'sfGuardPermission', 'expanded' => true)));
You should be creating your own widget and exdending it from sfWidgetFormDoctrineChoice is the best start. Basically it will return html as php strings which will get echoed. It is simple enough to get your head around eventually.
To include your profile form when editing your main user form it is very simple, in the same sfGuardUserForm class:
$this->embedForm('profile', new sfGuardUserProfileForm($this->getObject->NAME_OF_PROFILE_RELATIONSHIP));
That last call is off the top of my head so the syntax might be wrong so check it out, also replace the relationship with the name of your profile relationship of course.
First off, you have to put the new configure() in UserAdmin form (backend), not the regular User from (frontend).
Then, your configure() method will have the new widget declaration:
$this->setWidget('permission_list', new sfWidgetFormDoctrineChoice(array(
'muliple' => true, // this makes checkboxes (default=false=radio)
'model' => sfGuardPermission,
'expanded' => true // changes from select menu -> radio or check (based on 'multiple' setting)
)));
Good luck:)

Categories