Swagger: Where to set an API-Key for Authorization - annotations

I use Nelmio APi Doc 3.4. Swagger.
I want to use an apiKey authorization for my api.
I set the configuration in nelmio_api_doc.yaml:
nelmio_api_doc:
documentation:
schemes: [https]
securityDefinitions:
app_api_key:
type: apiKey
description: 'App Api Key'
name: Authorization
in: header
security:
- app_api_key: []
An in my Controller I set the parameter in the annotations:
....
#SWG\Parameter(
* name="Authorization",
* in="header",
* required=true,
* type="string",
* default="PUT HERE THE KEY",
* description="Authorization"
* )
*/
public function getProductAction()
{
....
}
But where do I set my ApiKey? For example I have an apiKey "abc123" and I want to check it against the insert key?
I dont understand where this function is. Can someone help me with this?

I think you should use the specific annotation for security authorizations:
use Nelmio\ApiDocBundle\Annotation as Nelmio;
/**
* #Nelmio\Security(name="app_api_key"),
* #SWG\Get()
*/
public function getProductAction()
{
//...
}

Related

Symfony FOSRestBundle error : Call to a member function get() on null. [Routing or Config error]

My problem : I've a symfony 3 app. One Bundle for Rest Route (so my bundle is a rest API) and another Bundle who manage the front (Twig + Ajax).
I use fos_rest but it seem makes problems.
My config.yml:
fos_rest:
routing_loader:
include_format: false
view:
view_response_listener: true
format_listener:
rules:
- { path: '^/rest', priorities: ['json'], fallback_format: 'json' }
- { path: '^/', stop: true }
My routing.yml :
front:
resource: '#FrontBundle/Controller'
type: annotation
api:
resource: '#AppBundle/Controller'
type: rest
prefix: '/rest'
and one basic route in my RestController :
/**
* #Rest\View()
* #Rest\Get("/participants")
*
* #param Request $request
* #return mixed
*/
public function getParticipantsAction(Request $request)
{
$participants = $this->get('doctrine.orm.entity_manager')
->getRepository('AppBundle:Participant')
->findAll();
if (empty($participant)) {
return new JsonResponse(['message' => 'There is no participants'], Response::HTTP_NOT_FOUND);
}
return $participants;
}
I test my route with postman and it send me an error Error: Call to a member function get() on null
Try with: $participants = $this->get('doctrine.orm.default_entity_manager')...
or with $participants = $this->getDoctrine()...

Can't resolve route - basic login

so I'm currently looking into Neos CMS and wanted to create a very basic login logic. [for practice]
I basically followed: http://flowframework.readthedocs.io/en/stable/TheDefinitiveGuide/PartIII/Security.html#authentication
My Code: [neos/ being the root dir]
Routes: [neos/Configuration/Routes.yaml] Note that's what I added in the beginning of the file, not the whole content of the file.
-
name: 'Authentication'
uriPattern: 'authenticate'
defaults:
'#package': 'VMP.Auth'
'#controller': 'Authentication'
'#action': 'authenticate'
AuthenticationController.php [neos/Packages/Plugins/VMP.Auth/Classes/VMP/Auth/Controller/]
<?php
namespace VMP\Auth\Controller;
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Mvc\ActionRequest;
use TYPO3\Flow\Security\Authentication\Controller\AbstractAuthenticationController;
class AuthenticationController extends AbstractAuthenticationController {
/**
* Displays a login form
*
* #return void
*/
public function indexAction() {
}
/**
* Will be triggered upon successful authentication
*
* #param ActionRequest $originalRequest The request that was intercepted by the security framework, NULL if there was none
* #return string
*/
protected function onAuthenticationSuccess(ActionRequest $originalRequest = NULL) {
if ($originalRequest !== NULL) {
$this->redirectToRequest($originalRequest);
}
$this->redirect('someDefaultActionAfterLogin');
}
/**
* Logs all active tokens out and redirects the user to the login form
*
* #return void
*/
public function logoutAction() {
parent::logoutAction();
$this->addFlashMessage('Logout successful');
$this->redirect('index');
}
public function fooAction() {
print "lol";
}
}
NodeTypes.yaml [neos/Packages/Plugins/VMP.Auth/Configuration/]
'VMP.Auth:Plugin':
superTypes:
'TYPO3.Neos:Plugin': TRUE
ui:
label: 'Auth Login Form'
group: 'plugins'
Policy.yaml [neos/Packages/Plugins/VMP.Auth/Configuration/]
privilegeTargets:
'TYPO3\Flow\Security\Authorization\Privilege\Method\MethodPrivilege':
'VMP.Auth:Plugin':
matcher: 'method(TYPO3\Flow\Security\Authentication\Controller\AbstractAuthenticationController->(?!initialize).*Action()) || method(VMP\Auth\Controller\AuthenticationController->(?!initialize).*Action())'
roles:
'TYPO3.Flow:Everybody':
privileges:
-
# Grant any user access to the FrontendLoginLoginForm plugin
privilegeTarget: 'VMP.Auth:Plugin'
permission: GRANT
Settings.yaml [neos/Packages/Plugins/VMP.Auth/Configuration/]
TYPO3:
Neos:
typoScript:
autoInclude:
'VMP.Auth': TRUE
Flow:
security:
authentication:
providers:
'AuthAuthenticationProvider':
provider: 'PersistedUsernamePasswordProvider'
Index.html [neos/Packages/Plugins/VMP.Auth/Resources/Private/Templates/Authentication/]
<form action="authenticate" method="post">
<input type="text"
name="__authentication[TYPO3][Flow][Security][Authentication][Token][UsernamePassword][username]" />
<input type="password" name="__authentication[TYPO3][Flow][Security][Authentication][Token][UsernamePassword][password]" />
<input type="submit" value="Login" />
</form>
**Root.ts2 [neos/Packages/Plugins/VMP.Auth/Resources/TypoScript/]
prototype(VMP.Auth:Plugin) < prototype(TYPO3.Neos:Plugin)
prototype(VMP.Auth:Plugin) {
package = 'VMP.Auth'
controller = 'Authentication'
action = 'index'
}
Problem:
if I call: www.neos.dev/authenticate I get:
Validation failed while trying to call VMP\Auth\Controller\AuthenticationController->authenticateAction().
So I think, the route itself does work. I now added the login form of my VMP.Auth Plugin to some page and logged in (with an existing user). The login form uses /authenticate as its action, but now I get the following error:
Page Not Found
Sorry, the page you requested was not found.
#1301610453: Could not resolve a route and its corresponding URI for the given parameters. This may be due to referring to a not existing package / controller / action while building a link or URI. Refer to log and check the backtrace for more details.
I don't really know what's the issue here. I guess my routing is wrong but I can't see it.
your onAuthenticationSuccess method has:
$this->redirect('someDefaultActionAfterLogin');
which is probably triggered (correctly) now. That tries to redirect to an action someDefaultActionAfterLoginAction in your AuthenticationController but this action does not exist. For starters try
$this->redirectToUri('/') to just have a redirect to the homepage.

Symfony2 - Form submit does not work depending on a route of page

So I have this route:
/**
* #Route("/", name="homepage")
*
* #param Request $request
*
* #return Response
*/
public function indexAction(Request $request)
{
// ...
In this page is a correct form that was working some time ago.
{{ form_start(company_sign_up_form, {'action': path('homepage', { 'sign_up': 'company' }) }) }}
Here sign_up is a parameter that I am passing through the url.
Example: http://localhost/?sign_up=company
When I am submitting form I am redirected to the page without this sign_up parameter and both $form->isSubmitted() and $form->isValid() are giving me false.
But when I change the route from #Route("/", name="homepage") to #Route("/something", name="homepage") the submit is working just fine.
The only similar route that could conflict is the dynamic one:
/**
* #Route("/{page}", name="public", requirements={"page": "about|programs|contacts"})
*
* #param Request $request
* #param $page
*
* #return Response
*/
public function publicAction(Request $request, $page)
{
I tried changing this route to different, but it does not fix my issue.
Does anyone know the problem, why my form is not submitting properly with current route?
UPDATE
So I overcame the issue by modifying the route my form is in and refers to.
/**
* #Route("/{page}", name="homepage", defaults={"page": ""}, requirements={"page": "|home"})
*
* #param Request $request
*
* #return Response
*/
public function indexAction(Request $request)
{
So in this case I can access my homepage by http://localhost/ and http://localhost/home so if I set form action to /home, my form is submitted successfully.
Anyway, this is not the solution or answer, I leave it as it is and wait for better solution.
In the end problem was caused by login form. I had to modify check_path of each area that login logic would not be executed in same page as other forms.
main:
pattern: ^
anonymous: ~
provider: main
context: primary_auth
form_login:
login_path: /
check_path: /login_check
default_target_path: /authorization
logout:
path: /logout
target: homepage
remember_me:
secret: '%secret%'
lifetime: 31536000

HWIOAuthBundle - FOSUserBundle - Symfony 2 - Redirect to custom path after login with facebook

Reflected the following problem after the user login with the Facebook account: that is redirected to the following route /#_=_
How can I redirect it to this route instead: / Or to more to this /# ?
On the client side, I use the backbone.
Taking #Prynz's idea, we can get further and create a "redirect to page user comes from" this way:
1) In your firewall, take care to remove the following lines:
# security.yml
# ...
logout: true
logout:
path: /logout
target: /
As we will implment the logout ourselves to avoid redirecting to the specified target.
2) Add #Prynz's solution to your security.yml (or config.yml depending on your implementation)
oauth:
resource_owners:
google: "/login/check-google"
facebook: "/login/check-facebook"
twitter: "/login/check-twitter"
sensio_connect: "/login/check-sensio-connect"
login_path: /login
failure_path: /login
default_target_path: /welcome # THIS LINE CONTRIBUTES TO THE MAGIC
oauth_user_provider:
service: app.oauth_user_provider
3) In your routing, add a new controller (here, LoginController) before HWIO's imports:
fuz_app_login:
resource: "#FuzAppBundle/Controller/LoginController.php"
type: annotation
prefix: /
4) Create the corresponding controller:
<?php
namespace Fuz\AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
class LoginController
{
/**
* #Route("/login", name="login")
* #Method({"GET"})
*/
public function loginAction(Request $request)
{
if ($this->getUser())
{
// already-logged user accessed /login
return $this->redirect($request->headers->get('referer'));
}
else
{
// redirect to the login page
return $this->forward('HWIOAuthBundle:Connect:connect');
}
}
/**
* #Route("/logout", name="logout")
* #Method({"GET"})
*/
public function logoutAction(Request $request)
{
// we do a manual logout just to redirect the user to where he comes from
$this->container->get('security.context')->setToken(null);
return $this->redirect($request->headers->get('referer'));
}
/**
* #Route("/connect/{service}", name="connect")
* #Method({"GET"})
*/
public function connectAction(Request $request, $service)
{
// we overwrite this route to store user's referer in the session
$this->get('session')->set('referer', $request->headers->get('referer'));
return $this->forward('HWIOAuthBundle:Connect:redirectToService', array('service' => $service));
}
/**
* #Route("/welcome", name="welcome")
* #Method({"GET"})
*/
public function welcomeAction()
{
// on login success, we're redirected to this route...
// time to use the referer we previously stored.
$referer = $this->get('session')->get('referer');
if (is_null($referer))
{
return new RedirectResponse($this->generateUrl('home'));
}
return new RedirectResponse($referer);
}
}
5) relax.
You simply add default_target_path: /whatever/path/you/want to the oauth section under the firewall setup
oauth:
resource_owners:
facebook: '/login/check-facebook'
google: '/login/check-google'
windows: '/login/check-windows'
twitter: '/login/check-twitter'
login_path: /login
failure_path: /login
default_target_path: /whatever/path/you/want
Have a look at https://github.com/hwi/HWIOAuthBundle/issues/89
Redirect using javascript. Add following to the page.
<script>
// Handle facebook callback
if (window.location.hash && window.location.hash == '#_=_') {
window.location.hash = '';
}
</script>
If you want, you can redirect the users to the current page doing this way:
Add in your config.yml
hwi_oauth.target_path_parameter: "target_path"
In your view append the urls with:
&target_path=...
remember you can take the current route name with
app.request.get('_route')

FOSFacebookBundle does not call custom provider

I'm facing big issue while implementing FOSFacebookBundle.
I followed the docs and have following situation:
* when user clicks login a popup appears
* after user grants permission to the app, FB button is being changed (to Logout)
However, my custom provider is not called (only a constructor is called) - yes, I use a noobish debug method (creating empty files with the name of the class method :-)).
Anybody has any suggestion why? Any tips?
Edit
After some time of trying to solve that issue, I feel I'm lost.
Once again, here's my configuration:
app/config/config.yml:
fos_facebook:
file: %kernel.root_dir%/../vendor/facebook/src/base_facebook.php
alias: facebook
app_id: xxx
secret: xxx
cookie: true
permissions: [email, user_location]
app/config/routing.yml:
_security_login:
pattern: /login
defaults: { _controller: TestBundle:Main:login }
_security_check:
pattern: /login_check
defaults: { _controller: TestBundle:Main:loginCheck }
_security_logout:
pattern: /logout
defaults: { _controller: TestBundle:Main:logout }
app/config/security.yml
security:
factories:
-"%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml"
providers:
my_fos_facebook_provider:
id: my.facebook.user
fos_userbundle:
id: fos_user.user_manager
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: /login
check_path: /login_check
logout: true
anonymous: true
public:
pattern: ^/.*
fos_facebook:
app_url: "http://www.facebook.com/apps/application.php?id=xxx"
server_url: "http://symfonytest.com.dev/app_dev.php/"
login_path: /login
check_path: /login_check
provider: my_fos_facebook_provider
default_target_path: /
anonymous: true
logout: true
I'm also implementing code into twig template as shown in docs (also implemented snippet from #Matt).
I have the same workflow as you and my custom user provider is called correctly and everything is working fine.
The first thing that you need to check is: do you have a JavaScript script that redirects the user to the login_check route after it has successfully login into Facebook via the popup? This is important because calling the login_check route after a valid authentication will trigger the security mechanism of Symfony2 that will call the FOSFacebookBundle special security code that will then call your own custom user provider. I think you may be just missing this small piece.
Here the pieces of JavaScript code required to make it work (using jQuery):
$(document).ready(function() {
Core.facebookInitialize();
});
var Core = {
/**
* Initialize facebook related things. This function will subscribe to the auth.login
* facebook event. When the event is raised, the function will redirect the user to
* the login check path.
*/
facebookInitialize = function() {
FB.Event.subscribe('auth.login', function(response) {
Core.performLoginCheck();
});
};
/**
* Redirect user to the login check path.
*/
performLoginCheck = function() {
window.location = "http://localhost/app_dev.php/login_check";
}
}
I put here my security.yml just to help you check for differences with your own file:
security:
factories:
- "%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml"
providers:
acme.facebook_provider:
# This is our custom user provider service id. It is defined in config.yml under services
id: acme.user_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
public:
pattern: ^/
fos_facebook:
app_url: "http://www.facebook.com/apps/application.php?id=FACEBOOK_APP_ID"
server_url: "http://localhost/app_dev.php/"
default_target_path: /
login_path: /login
check_path: /login_check
provider: acme.facebook_provider
anonymous: true
logout: true
And my service definition for the custom user provider we use:
services:
acme.user_provider:
class: Application\AcmeBundle\Security\User\Provider\UserProvider
arguments:
facebook: "#fos_facebook.api"
entityManager: "#doctrine.orm.entity_manager"
validator: "#validator"
You also need to create a new route for the /login_check, /login and /logout paths. Those route will be hooked by Symfony2 for the security process. Here an example of the implementation of the actions in a controller called MainController in my cases:
<?php
namespace Application\AcmeBundle\Controller;
use ...;
class MainController extends Controller
{
/**
* This action is responsible of displaying the necessary informations for
* a user to perform login. In our case, this will be a button to connect
* to the facebook API.
*
* Important notice: This will be called ONLY when there is a problem with
* the login_check or by providing the link directly to the user.
*
* #Route("/{_locale}/login", name = "_security_login", defaults = {"_locale" = "en"})
*/
public function loginAction()
{
if ($this->request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $this->request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $this->request->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render('AcmeBundle:Main:login.html.twig', array(
'error' => $error
));
}
/**
* This action is responsible of checking if the credentials of the user
* are valid. This will not be called because this will be intercepted by the
* security component of Symfony.
*
* #Route("/{_locale}/login_check", name = "_security_check", defaults = {"_locale" = "en"})
*/
public function loginCheckAction()
{
// Call intercepted by the Security Component of Symfony
}
/**
* This action is responsible of login out a user from the site. This will
* not be called because this will be intercepted by the security component
* of Symfony.
*
* #Route("/{_locale}/logout", name = "_security_logout", defaults = {"_locale" = "en"})
*/
public function logoutAction()
{
return $this->redirect('index');
}
}
Hope this help, if you have more questions or I misunderstand something from your problem, don't hesitate to leave a comment.
Regards,
Matt