Typo3 extbase User Auth Service - service

I try to write a service module, that fetches userdata from a webservice. I found this tutorial, but it shows the 'old' way of building extensions. Is it possible to write a extbase-extension like this? How it should look like?

Extbase ("the new way") is about MVC, not about auth services, thus this tutorial is still valid.
Claus Due (an Extbase specialist) wrote an auth extension, maybe you want to study his code: https://github.com/NamelessCoder/google_auth

Related

TYPO3: How to use an external PHP Script (in fileadmin), where i can check the cookie

I'm using TYPO3 11.3.3 for my server and i need a PHP Script, that can read and check the typo3_fe cookie. Are there any solutions? I can't use an extension and I have to keep it simple.
What exactly should the PHP script do apart from reading the cookie?
You can use a TypoScript condition to check if the cookie is present:
[request.getCookieParams()['foo'] == 1]
See the documentation for details.
The only way would be a content object USER. Check out the documentation.
Example
page = PAGE
page.10 = USER_INT
page.10 {
userFunc = Vendor\ExtensionName\ExampleTime->printTime
}
However the doc also states
The property includeLibs has been removed in TYPO3 8.0. In earlier
versions the userFunc classes were sometimes stored in fileadmin/ -
this is no longer possible out of the box and not recommended.
For the best result you should always, without exception, place your
class files in an extension, define composer class loading for this
extension and add this extension as a dependency of your project.
Then, your classes will load without issues when you refer to them by
their class name.
Cookies are being sent along with the request. With that being said, the best way to check for the cookies is Middlewares. With the middlewares you can check for the sent cookies and evaluate them with your script.
Here is the documentation about middlewares.
This might be helpful as well https://stackoverflow.com/a/63951593/7162477
Best regards

eID REST interface with authentication in Typo3

I'm providing an eID page as an REST interface. Now I want to protect this page with an API key or similar. How can this be achieved in Typo3 8.7?
Actually it looks like this can only be done by logging in via frontend (FE) or backend (BE) and check the login status in the eID controller class.
For TYPO3 v8, you should check out the EXT:restler extension instead of using eID.
eID is meant for calls where you have to do basically everything on your own.
For TYPO3 v9, the PSR-15 middleware concept allows to individually build custom REST APIs and integrations with other solutions like SlimPHP: https://github.com/b13/slimphp-bridge
You can expect a given URL-paramter, maybe even as a post param.
Put your eID-page-configuration (typoscript) in a condition requesting this paramter to be set. Otherwise genate an error-page.
If you want to handle multiple keys (maybe from a database table) you could use a userfunc for conditions.
If you want to handle a login in the call you need to initialize more from the TYPO3 frontend. then identify the paramters from the login form (some are hidden) and provide them. AFAIK POST and GEt paramaters work.

TYPO3 backend deeplink to page record

I am using version 8.7 of TYPO3 and intended to use a link that leads directly to the backend to edit a record (page). I tried anything like typo3/backend.php?edit=57 but got a error:
file not found
typo3/backend.php?edit=57 was the way to do it up until TYPO3 6.2, but the backend URL changed to typo3/index.php in TYPO3 7.6. It still works kind of, however you need a security token which is generated by the core. The URL now is typo3/index.php?route=%2Fmain&edit=57&token=.... There isn't really an easy way to generate URL with a valid token like that from outside TYPO3 though.
If you want to create a link inside a custom module to edit a record you can use \TYPO3\CMS\Backend\Utility\BackendUtility::editOnClick() or if you're using a Fluid template, the \TYPO3\CMS\Backend\ViewHelpers\Link\EditRecordViewHelper ViewHelper. More on that you can find here: https://docs.typo3.org/typo3cms/CoreApiReference/8.7/ApiOverview/Examples/EditLinks/
Using the extension pxa_siteimprove deep links are of the following form:
https://example.com/typo3/index.php?tx_siteimprove_goto=page:{page_uid}:{language_uid}
The parameter language_uid is optional. An example link to a page with uid 42 looks like this:
https://example.com/typo3/index.php?tx_siteimprove_goto=page:42
Optionally we can include a language uid (e.g. 1). Without a language uid set it defaults to 0:
https://example.com/typo3/index.php?tx_siteimprove_goto=page:42:1
If you want to create deep links for other purposes, you can look how this extension creates the deep link in Pixelant\PxaSiteimprove\Hooks\DeepLinkingHandler. In a first hook it just saves the page uid to the backend user session and in a later hook reuses this information to redirect to the desired page by setting the following global variable:
$GLOBALS['BE_USER']->uc['startModuleOnFirstLogin'] = 'web_layout->id=' . (int)$pageId . '&SET[language]=' . (int)$languageId;

Getting quizzes from Moodle

I'm trying to get Moodle's quizzes as JSON. I've already tried
http://desenvolvimento.imd.ufrn.br/qmmoodle/webservice/rest/server.php?wstoken=cf5a6639a4431341a40e7a75d8bb9cba&wsfunction=get_quizzes_by_course&moodlewsrestformat=json&course_id=2
To get all quizzes from a specific course. And
http://desenvolvimento.imd.ufrn.br/qmmoodle/webservice/rest/server.php?wstoken=cf5a6639a4431341a40e7a75d8bb9cba&wsfunction=get_quiz&moodlewsrestformat=json&quiz_id=3
To get a specific quiz.
I don't know what is wrong in my URL.
Thanks.
I think that you are referring to this document. If you read closely, you'll notice that it's a proposal about how the quiz web service should be written.
In fact, when I tried your query, to get all quizzes from a course, I got:
{"exception":"dml_missing_record_exception","errorcode":"invalidrecord",
"message":"Can not find data record in database table external_functions.",
"debuginfo":"SELECT * FROM {external_functions}
WHERE name = ?\n[array (\n 0 => 'get_quiz',\n)]"}
Moodle didn't found the external function get_quiz. That means... unfortunately, as of now, Moodle does not have a web service for quizzes.
If you feel adventurous, and what you need is just getting the quizzes, you could implement a web service to do that. The relevant moodle table about quizzes is mdl_quiz (for a full schema, look at this article), and here's the tutorial that shows how to implement it: Adding a web service to a plugin - Moodle Docs.
mod_quiz_get_quizzes_by_courses
is the function that does the job. How to call it
https://yourmoodledomain/webservice/rest/server.php?moodlewsrestformat=json&courseids[0]=courseid&wsfunction=mod_quiz_get_quizzes_by_courses&wstoken=yourusertoken

ASP.NET Web API Authorization with AuthorizeAttribute

Using the new ASP.NET Web API beta. I can not seem to get the suggested method of authenticating users, to work. Where the suggested approach seems to be, to add the [Authorize] filter to the API controllers. For example:
[Authorize]
public IEnumerable<Item> Get()
{
return itemsService.GetItems();
}
This does not work as intended though. When requesting the resource, you get redirected to a login form. Which is not very suitable for a RESTful webapi.
How should I proceed with this? Will it work differently in future versions?, or should I fall back to implementing my own action filter?
Double check that you are using the System.Web.Http.AuthorizeAttribute and not the System.Web.Mvc.AuthorizeAttribute. This bit me before. I know the WebAPI team is trying to pull everything together so that it is familiar to MVC users, but I think somethings are needlessly confusing.
Set your authentication mode to None:
<authentication mode="None" />
None Specifies no authentication. Your application expects only anonymous users or the application provides its own authentication.
http://msdn.microsoft.com/en-us/library/532aee0e.aspx
Of course then you have to provide some sort of authentication via headers or tokens or something. You could also specify Windows and use the built in auth via headers.
If this site is mixed between API and actual pages that do need the Forms setting, then you will need to write your own handling.
All the attribute does is return an HttpUnauthorizedResult instance, the redirection is done outside of the attribute, so its not the problem, its your authentication provider.
Finally, I've found a solution at:
ASP.NET MVC 4 WebAPI authorization
This article shows how you can fix this issue.
You are being redirected to login page because forms authentication module does this automatically. To get rid of that behavior disable forms authentication as suggested by Paul.
If you want to use more REST friendly approach you should consider implementing HTTP authorization support.
Take a look at this blog post http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-membership-provider/
ASP.NET 5 Introduced the new Microsoft.AspNet.Authorization System which can secure both MVC and Web API controllers.
For more see my related answer here.
Update:
At that time 2 years ago it was Microsoft.AspNetCore.Authorization.
As #Chris Haines pointed out. now it resides on
Microsoft.AspNetCore.Authorization.
From .NET core 1.0 to 2.0 many namespaces have been moved i think.
And spread functionality between .net classic and core was obscure.
That's why Microsoft introduced the .net standard.
.net standard
Also, look at my answer for:
How to secure an ASP.NET Web API
There is a NuGet package I have created which you can use for convenience.
If you're using a Role, make sure you have it spelled correctly :
If your role is called 'Administrator' then this - for instance will not work :
[System.Web.Http.Authorize(Roles = "Administator")]
Neither will this :
[System.Web.Http.Authorize(Roles = "Administrators")]
Oops...
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Produces("application/json")]
[Route("api/[controller]")]
public class CitiesController : Controller
{
[HttpGet("[action]")]
public IActionResult Get(long cityId) => Ok(Mapper.Map<City, CityDTO>(director.UnitOfWork.Cities.Get(cityId)));
}
Use
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
Filter with authentication type