Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session loss when refreshing the page. #101

Open
maarccnj93 opened this issue Sep 19, 2024 · 1 comment
Open

Session loss when refreshing the page. #101

maarccnj93 opened this issue Sep 19, 2024 · 1 comment

Comments

@maarccnj93
Copy link

I have this code lo listen SignedIn. This part seems to work fine, I retrieve the User from SSO and save it as User in my database and log in. The problem is when I reload the page, I realize that the session has been lost. What could be the error?

Event::listen(\Slides\Saml2\Events\SignedIn::class, function (\Slides\Saml2\Events\SignedIn $event) {
            $messageId = $event->getAuth()->getLastMessageId();

            // your own code preventing reuse of a $messageId to stop replay attacks
            $samlUser = $event->getSaml2User();

            $userData = [
                'id' => $samlUser->getUserId(),
                'attributes' => $samlUser->getAttributes(),
                'assertion' => $samlUser->getRawSamlAssertion()
            ];

            if (isset($userData['attributes']['urn:oid:1.2.840.113549.1.9.1']['0'])){
                $email = $userData['attributes']['urn:oid:1.2.840.113549.1.9.1']['0'];
                $name = $userData['attributes']['urn:oid:2.5.4.42']['0'];
                $surnames = $userData['attributes']['urn:oid:2.5.4.4']['0'];
                $userName = $userData['attributes']['urn:oid:0.9.2342.19200300.100.1.1']['0'];
            }


            $user = User::where('email', $email)->first();

            if (!$user) {
                $user = User::create([
                    'name' => $name ." ".$surnames,
                    'email' => $email,
                    // Si no tienes una contraseña, puedes generar una aleatoria
                    'password' => Hash::make(Str::random(24)),
                    'username' => $userName
                ]);
            }else{
                $user->update([
                    'name' => $attributes['name'] ?? $name ." ".$surnames,
                ]);
            }

            $roles = app(LdapDataService::class);
            $roles = $roles->getUserGroupApli($user->username);

            foreach ($roles as $role) {
                $role = Role::findByName($role, 'web')->first();

                if(!$role){
                    Role::create(['guard_name' => 'web', 'name' => $role]);
                }

                $user->assignRole($role);
            }

            Auth::guard('web')->login($user);
           
        });

And I also have a "CheckIfAdmin" midelware which is where I detect that the login is lost when refreshing the page

 private function checkIfUserIsAdmin($user)
    {
        // return ($user->is_admin == 1);
        return true;
    }

    private function respondToUnauthorizedRequest($request)
    {
        if ($request->ajax() || $request->wantsJson()) {
            return response(trans('backpack::base.unauthorized'), 401);
        } else {
            return redirect()->guest(backpack_url('login'));
        }
    }

   
    public function handle($request, Closure $next)
    {

        if (!auth()->check()) {
            //When I do refresh this returns null
        }else{
           // The first load on page auth is OK!
        }

        if (backpack_auth()->guest()) {
            return $this->respondToUnauthorizedRequest($request);
        }

        if (! $this->checkIfUserIsAdmin(backpack_user())) {
            return $this->respondToUnauthorizedRequest($request);
        }

        return $next($request);
    }
@Frameck
Copy link

Frameck commented Nov 11, 2024

i solved this problem by overriding the acs route of the package to point to my controller where i added the session cookies to the response header.

routes/web.php

Route::group([
    'prefix' => config('saml2.routesPrefix'),
    'middleware' => array_merge(['saml2.resolveTenant'], config('saml2.routesMiddleware')),
], function () {
    Route::get('/{uuid}/logout', array(
        'as' => 'saml.logout',
        'uses' => 'Slides\Saml2\Http\Controllers\Saml2Controller@logout',
    ));

    Route::get('/{uuid}/login', array(
        'as' => 'saml.login',
        'uses' => 'Slides\Saml2\Http\Controllers\Saml2Controller@login',
    ));

    Route::get('/{uuid}/metadata', array(
        'as' => 'saml.metadata',
        'uses' => 'Slides\Saml2\Http\Controllers\Saml2Controller@metadata',
    ));

    Route::post('/{uuid}/acs', array(
        'as' => 'saml.acs',
        'uses' => 'App\Http\Controllers\SSOAuthController@acs',
    ));

    Route::get('/{uuid}/sls', array(
        'as' => 'saml.sls',
        'uses' => 'Slides\Saml2\Http\Controllers\Saml2Controller@sls',
    ));
});

controller

public function acs(Auth $auth): Redirector|RedirectResponse
{
    $errors = $auth->acs();

    if (!empty($errors)) {
        $error = $auth->getLastErrorReason();
        $uuid = $auth->getTenant()->uuid;

        logger()->error('saml2.error_detail', compact('uuid', 'error'));
        session()->flash('saml2.error_detail', [$error]);

        logger()->error('saml2.error', $errors);
        session()->flash('saml2.error', $errors);

        return redirect(config('saml2.errorRoute'));
    }

    $user = $auth->getSaml2User();

    event(new SignedIn($user, $auth));

    // set cookies so that the browser can remember the session
    $res = response()->noContent();
    $res->headers->setCookie(new Cookie('XSRF-TOKEN', csrf_token(), now()->addDay()));
    $res->headers->setCookie(new Cookie(config('session.cookie'), session()->getId(), now()->addDay()));

    Log::info('Sending cookie with redirect response', [
        'headers' => $res->headers->all(),
    ]);

    $redirectUrl = $user->getIntendedUrl();

    if ($redirectUrl) {
        // pass the headers to the redirect
        return redirect($redirectUrl, headers: $res->headers->all());
    }

    return redirect($auth->getTenant()->relay_state_url ?: config('saml2.loginRoute'), headers: $res->headers->all()); // pass the headers to the redirect
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants