Error on custom middleware checking the value returned on a Model custom Function Laravel 5.1 - laravel-5.1

I have an account email confirmation for my Laravel app, then I want to check when the user tries to log in, if the user has activated his account.
I found this: https://laracasts.com/discuss/channels/general-discussion/how-to-test-if-a-user-which-tries-to-log-in-is-confirmed-yet
I have a custom model function isActivated that only return the state attibute(boolean type, named estado in spanish) on user model.
On my User Model:
public function isActivated()
{
return $this->estado;
}
I created my middleware similar as the link above provided advices, then I registered in App/Http/Kernel.php as a middleware route
The problem comes when I assign my middleware to my route (instead of create the construct function in my controller, I want this middleware just on post request of the login controller).
When I tried to log in throws an error:
Fatal Throwable Error:
Fatal Error: Call to a member function isActivated() on null
My middleware looks exacts as the link
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class RedirectIfNotMailActivated
{
/**
* The Guard implementation.
*
* #var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* #param Guard $auth
* #return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ( ! $this->auth->user()->isActivated()) {
return redirect('/login')
->with('mensaje',
'¡Lo sentimos, no ha confirmado su cuenta aún!');
} else {
return $next($request);
}
}
}
The fun part: if I add the content of the handle function of my middleware in the App/Http/Middleware/Authenticate(auth middleware) and then I group and attach some routes to this middleware, this works as expected (not allowing non confirmed users to login)
The problem is that I have a polimorphic relationship in users table for user type (Admin and Customer) so I attached and grouped the admins control panel to auth middleware because I need to restict the access to control panel just for authenticated users and admin type(not allowed for customer user type).
Restriction only takes part on Admin User type.
And of coursethis let the Customer user types can login because I have nothing that restict the if his account is confirmed or not.
What am I doing wrong... The isActivated model function work ok when added in auth middleware, but no when I use this same approach in my custom middleware.
Thanks....
EDITED
My middleware asigned to my post method for my login controller
Route::post('/login', [
'middleware' => 'activated.email',
'uses' => 'loginController#store'
]);
PD: sorry for long post and bad english habilities, it is not my first language :(

You have a problem with our logic. Your login path should not be protected with am activated user, because middleware is executed before the request, so the user can't event attempt to login in your case and you get an error because of that.
What you can do instead is add your isActivated() check in the Authenticate middleware, so there you'll have a logged user and $this->auth->user() won't be null.

Related

User Sessions with Vaadin Flow

I am currently a budding Java developer that wants to get into Vaadin development and currently trying to implement User Session login for my application. I have read about the content regarding the usage of VaadinServlets to do so : https://vaadin.com/docs/v10/flow/advanced/tutorial-application-lifecycle.html.
After relentlessly digging through API documentations and sample codes, I still am not able to understand how to implement the User Sessions for a specific user that logs into my platform. From what I understand is that, I can initialize my user session by using what i have implemented below.
However my aims for the application are slightly different:
[Use Case]
1.User logs in with their specific credentials.
2.Gets Redirected to a SecuredPage (which will create a User Session storing the user's username and retrieves a token?)
3.After 2-3mins of inactivity, the User will get forced out of the SecuredPage and Session closes?
#WebServlet(urlPatterns = "/*", name = "VaadinFlowServlet", asyncSupported = true)
#VaadinServletConfiguration(heartbeatInterval = 5, productionMode = false)
public class LoginServlet extends VaadinServlet implements SessionInitListener, SessionDestroyListener {
private static final Logger LOGGER = LoggerFactory.getLogger(LoginServlet.class);
// <Method> ::servletInitialized():: -> handles most of the servlet customization. (write my servlet customization under this function.
// ::getService():: -> returns a VaadinServletService type?
// ::addSessionInitListener(this):: -> An event listener that can be registered to a VaadinService to get an event -> when a new Vaadin service session is initialized for that service.
// ::addSessionDestroyListener(this):: -> A listener that gets notified when a Vaadin service session is no longer used.
#Override
protected void servletInitialized() throws ServletException {
super.servletInitialized();
getService().addSessionInitListener(this);
getService().addSessionDestroyListener(this);
}
// <Method> ::sessionInit:: -> Starts Session?
// <Parameter> ::SessionInitEvent:: -> Event gets fired when a new Vaadin service session is initialized for a Vaadin service.
#Override
public void sessionInit(SessionInitEvent event) throws ServiceException{
// Do Session start stuff here
// Creates a Session?
LOGGER.info("session init() "
+ " Session-ID: " + event.getSession().getSession().getId()
+ " CSRF: " + event.getSession().getCsrfToken());
}
// <Method> ::sessionDestroy:: -> Stops Session?
// <Parameter> ::SessionDestroyEvent:: -> Event fired when a Vaadin service session is no longer in use.
#Override
public void sessionDestroy(SessionDestroyEvent event) {
// Do session end stuff here
LOGGER.info("session destory()");
}
}
1
So I was wondering if anybody can help me understand this matter better? Fully Appreciated
tl;dr
The mere existence of a custom-defined user-login object stored as an attribute in the key-value store of your VaadinSession represents the user having successfully authenticated. No need for all the session-listener code you wrote.
Let Vaadin do the heavy-lifting
I suspect you are working too hard.
There is no need for your session listeners. Vaadin handles nearly all the Java Servlet details on our behalf.
No need for the redirects. As a Vaadin developer, you are in full control of the content displayed in the browser tab/window, so you can switch between login form and main app content. Caveat: I am new to the #Route feature in Vaadin Flow, so there may be a niftier way with that feature to flip between login and main-content. And if you are using #Route for multiple views, each of those views should test for the authentication as described below.
VaadinSession
At the entry point of your Vaadin app code, retrieve the current VaadinSession object. This VaadinSession is a wrapper around the javax.servlet.http.HttpSession class defined by the Java Servlet spec. Vaadin automatically instantiates a session when the user’s browser first connects to your Vaadin web app (actually, Vaadin wraps the session instantiated by your web container). The session is automatically closed when the browser closes its tab/window, a time-out of inactivity occurs, or you programmatically close the session.
VaadinSession vaadinSession = VaadinSession.getCurrent() ;
Session attributes (key-value store)
Interrogate that session object’s key-value store known as “attributes”. The key is of type String and the value is of type Object (the superclass of all Java objects). After retrieving the Object object, you cast to the known class. You know the class, because it is your code that stored the attribute.
Your user-login class
You would have defined a class to store your user-login related info. Perhaps you named it UserLogin.
Something like:
public class UserLogin {
// Member values.
String userName ;
Instant whenAuthenticated ;
// Constructor.
public UserLogin( String userNameArg , Instant whenAuthenticatedArg ) {
this.userName = userNameArg ;
this.whenAuthenticated = whenAuthenticatedArg ;
}
}
Attempt to retrieve object of your user-login class from the session’s key-value store
Retrieve such an object of that type from the session attributes key-value store.
String attributeName = "my-user-login" ;
UserLogin userLogin = vaadinSession.getAttribute( attributeName ) ;
Rather than invent an attribute name, you could just use the class name. The Class class lets you ask for the name of a class as text.
String attributeName = UserLogin.class.getName() ;
UserLogin userLogin = vaadinSession.getAttribute( attributeName ) ;
If you want to use the class name as the key in this way, the VaadinSession class provides a shortcut.
UserLogin userLogin = vaadinSession.getAttribute( UserLogin.class ) ;
Check to see if your UserLogin object is null. If you retrieved a null, then you know you have not yet stored an attribute (or willfully stored a null).
If not null, it means your user already has an active UserLogin object stored. How could they be logged-in already if the entry point of your app is executing? This can happen if the user hits the Reload button on their browser window. (Train your user not to do so on a single-page web app such as Vaadin.)
Outline of code to write
UserLogin userLogin = vaadinSession.getAttribute( UserLogin.class ) ;
if( Objects.isNull( userLogin ) ) {
… display login form …
… when authenticated, instantiate a `UserLogin` and store as attribute …
if( authenticationSuccessful ) { // Testing some did-user-authenticate variable you defined in your login-form.
Instant whenAuthenticated = Instant.now() ; // Capture the current moment in UTC.
UserLogin userLogin = new UserLogin( userName , whenAuthenticated ) ;
VaadinSession.getCurrent().setAttribute( UserLogin.class , userLogin ) ; // Using class name as the `String` key tracking this `userLogin` object.
… switch content of the tab/window from authentication form to your main app content …
}
} else { // Else not null. User already authenticated. User may have hit "Reload" button in browser.
… display app content …
… perhaps log this event … maybe user needs to be trained to not hit Reload on a Single-Page Web App …
}
By the way… the discussion above about sessions is scoped to each user’s own connection to your web app in a single web browser tab/window.
At some point you may look for a hook into the lifecycle of your entire web app, before the first user connects and/or after the last user disconnects, learn about the hook defined in the Java Servlet spec. This hook is the ServletContextListener interface, where “context” means your web app as a whole. This is standard Java Servlet stuff, not at all specific to Vaadin, but Vaadin is actually a Servlet (perhaps the most sophisticated Servlet ever) so this context listener paradigm applies.
You write a class implementing that interface, by writing the before-first-user and the after-last-user methods. Identify your class to the web container by annotating #WebListener (or alternative means). Search Stack Overflow as this has been covered multiple times already.

Google authentification always ask authorization

After having connected a user from Google OAuth, when this one wishes to reconnect during a next session requiring the selection of his google account, the permission is asked again.
According to the documentation, the behavior of the parameter prompt that is responsible for authorization requests is as follows:
If no value is specified and the user has not previously authorized
access, then the user is shown a consent screen.
The user should therefore not have to reorder his consent.
The only answer envisaged was the one on this question : login with google always asks user consent
Because I also work locally without secure HTTP, but he assumes that a cookie policy is present which is not the case.
How could I do to resolve this anomaly ?
Edit :
/**
* Create a new OAuth2Client with the credentials previously loads
*/
private getOAuth2() : OAuth2Client {
return new OAuth2(
this.credentials.client_secret,
this.credentials.client_id,
this.credentials.redirect_uris[0]
);
}
/**
* Create connection URL for the given scopes
* #param scopes
*/
public url(scopes: Array<string>) : string {
return this.client.generateAuthUrl({
access_type: "offline",
scope: scopes
});
}
// The scope used to generate URL is 'https://www.googleapis.com/auth/youtube.readonly'
// this.client refer to a client which is load by getOAuth2
// and use only for the generation of URL's.

How to set permissions dynamically in Microsoft.AspNet.Mvc.Facebook.FacebookAuthorize?

Controller
public partial class HomeController
{
private static String[] userPermissions;
public HomeController()
{
var MyPermission = Convert.ToString(TempData["MyPermission"]);
userPermissions = (MyPermission).Split(',');
}
[Microsoft.AspNet.Mvc.Facebook.FacebookAuthorize(userPermissions)]
public virtual ActionResult MyActionMethod()
{
return View();
}
}
Overload
Compilation Error
In the above block, we have following code
[Microsoft.AspNet.Mvc.Facebook.FacebookAuthorize(userPermissions)]
It is giving below compilation error...
Not sure if it helps but this is how I let users add additional permissions.
/// <summary>
/// Use this method when an action fails due to lack of priviligies. It will redirect user to facebook with provided permission request.
/// Refactor to handle list of request.
/// </summary>
/// <param name="permission"></param>
private static void AddAdditionalPermissions(string permission)
{
System.Diagnostics.Trace.TraceInformation(permission + " not authorized for user.");
string facebook_urlAuthorize_base = "https://graph.facebook.com/oauth/authorize";
string scope = permission; //see: https://developers.facebook.com/docs/authentication/permissions/ for extended permissions
string urlAuthorize = facebook_urlAuthorize_base;
urlAuthorize += "?client_id=" + AppId;
urlAuthorize += "&redirect_uri=" + "https://mydomainnamehere.nu/";
urlAuthorize += "&scope=" + scope;
//redirect the users browser to Facebook to ask the user to authorize our Facebook application
HttpContext.Current.Response.Redirect(urlAuthorize, true); //this cannot be done using WebRequest since facebook may need to show dialogs in the users browser
}
It is my understanding that you cannot dynamically assign anything to an attribute argument (as the error message backups up).
I do something with my Custom Membership Provider that I think you could adapt to meet your goal. I wanted a roles/rights setup defining user access to various parts of the system without needing to assign a bunch of individual rights to the users but still have very granular control of what each role can do. I followed the approach here (with some changes) to accomplish this.
The approach I would take if there is a need to do this on the fly in your scenario is define a constant Role to use in the FacebookAuthorize attribute for an ActionMethod and then in whatever is handling your permission checking pass (or have it look up) the array of permissions for each "role". This way the "role" you assign to the AuthorizeAttribute is a constant.

Grails Spring Security: Logging in with a target URL skips post authentication workflow

In my grails app I have customized the post authorization workflow by writing a custom auth success handler (in resources.groovy) as shown below.
authenticationSuccessHandler (MyAuthSuccessHandler) {
def conf = SpringSecurityUtils.securityConfig
requestCache = ref('requestCache')
defaultTargetUrl = conf.successHandler.defaultTargetUrl
alwaysUseDefaultTargetUrl = conf.successHandler.alwaysUseDefault
targetUrlParameter = conf.successHandler.targetUrlParameter
useReferer = conf.successHandler.useReferer
redirectStrategy = ref('redirectStrategy')
superAdminUrl = "/admin/processSuperAdminLogin"
adminUrl = "/admin/processAdminLogin"
userUrl = "/admin/processUserLogin"
}
As you can from the last three lines in the closure above, depending on the Role granted to the logging in User I am redirecting her to separate actions within the AdminController where a custom UserSessionBean is created and stored in the session.
It works fine for a regular login case which in my app is like so:
User comes to the app via either http://localhost:8080/my-app/ OR http://localhost:8080/my-app/login/auth
She enters her valid login id and password and proceeds.
The app internally accesses MyAuthSuccessHandler which redirects to AdminController considering the Role granted to this User.
The UserSessionBean is created and stored it in the session
User is taken to the app home page
I have also written a custom MyUserDetailsService by extending GormUserDetailsService which is correctly accessed in the above flow.
PROBLEM SCENARIO:
Consider a user directly accessing a protected resource (in this case the controller is secured with #Secured annotation) within the app.
User clicks http://localhost:8080/my-app/inbox/index
App redirects her to http://localhost:8080/my-app/login/auth
User enters her valid login id and password
User is taken to http://localhost:8080/my-app/inbox/index
The MyAuthSuccessHandler is skipped entirely in this process and hence my UserSessionBean is not created leading to errors upon further use in places where the UserSessionBean is accessed.
QUESTIONS:
In the problem scenario, does the app skip the MyAuthSuccessHandler because there is a target URL for it to redirect to upon login?
Can we force the process to always pass through MyAuthSuccessHandler even with the target URL present?
If the answer to 2 is no, is there an alternative as to how and where the UserSessionBean can still be created?
You can implement a customized eventListener to handle the post-login process, without disrupting the original user requested url.
In config.groovy, insert a config item:
grails.plugins.springsecurity.useSecurityEventListener = true
In you resources.groovy, add a bean like this:
import com.yourapp.auth.LoginEventListener
beans = {
loginEventListener(LoginEventListener)
}
And create a eventListener in src/groovy like this:
package com.yourapp.auth
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent
import org.springframework.web.context.request.RequestContextHolder as RCH
class LoginEventListener implements
ApplicationListener<InteractiveAuthenticationSuccessEvent> {
//deal with successful login
void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
User.withTransaction {
def user = User.findByUsername(event.authentication.principal.username)
def adminRole = Role.findByAuthority('ROLE_ADMIN')
def userRole = Role.findByAuthority('ROLE_USER')
def session = RCH.currentRequestAttributes().session //get httpSession
session.user = user
if(user.authorities.contains(adminRole)){
processAdminLogin()
}
else if(user.authorities.contains(userRole)){
processUserLogin()
}
}
}
private void processAdminLogin(){ //move admin/processAdminLogin here
.....
}
private void processUserLogin(){ //move admin/processUserLogin here
.....
}
}
Done.
1) Yes, because it is an "on-demand" log in.
2) Yes, you can set it to always use default. The spring security plugin has a setting for it "successHandler.alwaysUseDefault" change that to true it defaults to false.
Also if you need more details check out the spring docs look for the Setting a Default Post-Login Destination section.
3) If you want to still create the user session bean and then redirect to the original URL you have two options create the bean in an earlier filter or expose the needed data via a custom UserDetailsService. Personally I would go the route of a custom details service.

Problem with form handling in symfony

i'm new to symfony and i'm having the following issue creating login logic for application:
1) I have a form which is loaded by a slot in the layout.php file, the form contains a 'User' object, with only 2 properties: 'user_name'and 'password', and validation is taken care by symfony validator framework (both fields have 'required' validator set as you migh have guessed)
index page is accesed by action:
public function executeIndex(sfWebRequest $request)
{
$this->form = new UserFormLogin();
}
The form is loaded by something like this in the layout file:
2) I have a login action, which performs validation, here's the relevant code:
protected function processLoginForm(sfWebRequest $request, sfForm $form)
{
form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
...Some code to retrieve from db, check credentials etc...
}
else
{
$this->redirect('users/index');
}
}
public function executeLogin(sfWebRequest $request){
$this->forward404Unless($request->isMethod(sfRequest::POST));
$this->form = new UserFormLogin();
$this->processLoginForm($request, $this->form);
}
3) All the above so (theoretically) when a user inputs non-valid credentials returns to index and shows error messages... but instead of getting the expected 'username is required' or something like that, it gives me the next error: "An object with the same "user_name" already exist.
Any ideas why is that? please help me, what i'm missing?
you are try to register new user form, so what are you doing right, no error, when the user enter the same user name you must redirect him the the index success, and if you try to register by used user name you will face the below validation message.

Resources