symfony 2 how to display the error after login with custom authentication handler - authentication

I have created an authentication handler and everything is working fine when the user authenticates with success...but when there is a failure I don't know how to return the failure error to my form and display it.
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
}
How should my function look like because I do not know how to pass $exception and redirect back to my form.

You probably want to display a message to the user.
You can display a flash message and redirect the user.
$request->getSession()->setFlash('error', $exception->getMessage());
If you look at the FosUserBundle they display a message direcly in the template
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/views/Security/login.html.twig
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Controller/SecurityController.php
Hope it's helpful
Best regard

Related

Teams Email of connected user into message extension teams, message extension continue after login

I've one trouble with my teams custom app. I'm making a custom app that return sign-in action to unlogged user when he try to use a search message extension. Now, my problem is:
How can I resume the query after the user logged?
I return to the user an auth composeExtension type that point to one route of my spa. The user make authentication and correctly return the accesstoken, but then it doesn't continue the search. I've already try call :
microsoftTeams.authentication.notifySuccess({ accesToken: oResponse.accessToken })
but it only close the opened popUp.
Please, help me. Thanks.

Laravel 6 verify email leaving database field null

I have setup my own custom notification for reaching out to my users to verify their email. They don't get their verification email at registration. They register, I call them and screen them, then approve their registration. After I approve them, they get a verification email. All this is working great. However, when the user clicks their verification link in their email, it takes them to the login page but in the database, the email_verified_at column never updates with a time stamp. I've followed multiple tutorials and can't figure out for the life of me why this is happening.
This is my notification function in my controller that I'm using for the screening process:
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable);
}
return (new MailMessage)
->subject(Lang::get('Verify Email Address'))
->line(Lang::get('Please verify email.'))
->action(
Lang::get('Verify Email Address'),
$this->verificationUrl($notifiable)
)
->line(Lang::get('If you did not create an account, no further action is required.'));
}
and here is my verification controller:
public function __construct()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
When I hover over the link in mailtrap, it has a valid URL and, as stated, redirects to the login screen.
I can supply any other code requested, I just didn't want to paste 5 files worth of code here if it wasn't necessary as all the other functionality seems to be working fine. If anyone can help me figure out why this is happening, it would be greatly appreciated.

How do I simply set the ModelStateError from the HandleUnauthorizedRequest method?

So what is happening is that I have a condition within my override of the HandleUnauthorizedRequest method in my custom authorize attribute. Up to this point, I've been throwing a 403 which gets picked up and redirects to a custom error page. Well now, that's not really what I want. What I actually want is to show the same login page but add a message to the validation summary "You do not have access to this resource.", that way it's a bit more user friendly. It'll indicate that your creds were good, but you don't belong here.
I thought something like this would work:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// passed authentication, failed authorization
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Controller.ViewData.ModelState.AddModelError("", "Not Authorized");
return;
}
base.HandleUnauthorizedRequest(filterContext);
}
But this isn't working. What's happening is that the login page simply reloads. So this makes me feel like I'm close, but I need that model error to show up.
Any ideas?
UPDATE:
It would seem that the Controller that I'm adding an error to here is actually controller of whichever action had the attribute that led to here. I need to somehow add the error to the login controller. Not sure if that's even possible.
You are calling the base method here:
base.HandleUnauthorizedRequest(filterContext);
If you are using Forms Authentication this base method simply redirects you to the login page. And a redirect means a new HTTP request from the client. The current context and whatever you stored in it is lost. Well, to be more precise, the base method is returning a 401 HTTP status code which is then intercepted by the FormsAuthenticationModule which redirects to the login page defined in your web.config. But this implementation details is not important.
What you could do is perform the redirect yourself to the login page instead of leaving it to the base method. You could do this by setting the filterContext.Result property to a RedirectToRouteResult instance. In this case you could pass the error message as a query string parameter.
UPDATE:
According to your updated question it seems that you are calling return; after setting the ModelState value and not calling the base method and thus no redirect will happen to the login url. You could in this case return some error view by setting the filterContext.Result to an instance of a ViewResult in which view you could use the value you stored in the ModelState.

Facebook Connect: User has logged in and given permissions, now what?

So i've been trying to get FB Connect working on my site, simply for login and authentication, using the Javascript SDK and following the code at:
https://developers.facebook.com/docs/guides/web/
So the button appears, i click it, a dialog pops up, i click that, presumably my site now has permission to know who i am...
Then what? The guide goes on to saying all the stuff I can access through the Facebook API, all the cool things about permissions, but presumably i need the user's ID or access token or something to get at this stuff. How is that given to me? left as a attribute on one of the elements? Left in a Javascript variable somewhere? Given as an argument to some callback? Thrown high into the heavens for me to receive via satellite downlink?
This is probably incredibly simple, but for the life of me i have not been able to figure it out. Facebook's tutorials have failed me, and so has Google. I want to get this in the Javascript, so I can immediately fill in form-data using the user's Facebook name, put a picture, etc. etc., and presumably send this all back to the server so the server can validate with Facebook that the data is real.
I'm assuming you're using the Login button? https://developers.facebook.com/docs/reference/plugins/login/
If you simply want form info, check out the registration plugin - https://developers.facebook.com/docs/plugins/registration/
However, to answer your question, make an API call to /me. For example:
FB.api('/me', function(user) {
if(user != null) {
// The user object now contains info about the logged in user
}
});
You should subscribe to the auth.login event and wrap the above API call in the successful response, i.e.:
FB.Event.subscribe('auth.login', function() {
// JS to run if when the user logs in, for example, the code snippet above
});

A better way of passing variables from controller to view in symfony

Hey.
I've got a login form with post as method. The action goes to 'auth/login' and will check the database if the user exists. If the user exists, I call the $this->getUser->setAuthenticated(true);. After this I want to redirect to a welcome page if success.
If the login failed, I would want to tell the user so in the view of course. But settings variables in the controller only if login failed, and check in the view if each of those variables are set, is a lot of work?
This means I have to check almost all variables I want to use in the view set from the controller. If it should happen that it is not set, and I just go ahead and echo it, I get an error from symfony, and production stage-mode-ish don't show anything but an 500 internal server error .
Thanks
EDIT:
This is my current, new and better solution. Still looking for feeback.
in /templates/loginSuccess
if ($sf_params->has('bad_login')) {
echo "Wrong username or password";
}
And in my controller:
$this->redirect('auth/login?bad_login=');
Take a look at how sfDoctrineGuardPlugin (the de-facto standard for authentication) does it: they created sfGuardValidatorUser and use it as a post validator in the signin form.
Advantage of this method: the form takes care of the username/password validation, you do not need to put that code in your action. It simplifies that to a simple $form->isValid() { $this->redirect("#homepage"); }.
It seems like you could use symfony's form to take care of the validation. Since the forms show errors built in, you could put this into the form validation and then your controller looks something like:
$form = new LoginForm;
if ($request->isMethod('post'))
{
if ($form->isValid())
{
$this->redirect('account');
}
else
{
// this would show the form, and since you put the login in the form validation it will show errors. You could have the username show the error
}
}
To do what you are doing though, I'd recommend this. That way you aren't accessing any parameters in the view as well.
Controller:
$this->bad_login = $this->getParameter('bad_login',false);
View:
if ($bad_login) { echo 'bad login'; }
Use forward()
Put all the logic required for the view population into separate method of a controller, and call it in both places.
Use cgratigny's solution - put login form and processing code in a single action, and redirect to welcome page if isMethod('post') && $login_success