Symfony 4.0
Proses ini tidak berubah dari symfony 3 ke 4 tetapi berikut adalah contoh penggunaan AbstractController yang baru direkomendasikan. Baik security.token_storage
dan session
layanan terdaftar di induk getSubscribedServices
metode sehingga Anda tidak perlu menambah orang-orang di controller Anda.
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use YourNameSpace\UserBundle\Entity\User;
class LoginController extends AbstractController{
public function registerAction()
{
$user = //Handle getting or creating the user entity likely with a posted form
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->container->get('security.token_storage')->setToken($token);
$this->container->get('session')->set('_security_main', serialize($token));
// The user is now logged in, you can redirect or do whatever.
}
}
Symfony 2.6.x - Symfony 3.0.x
Pada symfony 2.6 security.context
sudah usang dan tidak mendukung security.token_storage
. Pengontrol sekarang dapat menjadi:
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use YourNameSpace\UserBundle\Entity\User;
class LoginController extends Controller{
public function registerAction()
{
$user = //Handle getting or creating the user entity likely with a posted form
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$this->get('session')->set('_security_main', serialize($token));
}
}
Meskipun ini sudah usang, Anda masih dapat menggunakan security.context
karena telah dibuat agar kompatibel dengan versi sebelumnya. Bersiaplah untuk memperbaruinya untuk Symfony 3
Anda dapat membaca lebih lanjut tentang 2.6 perubahan untuk keamanan di sini: https://github.com/symfony/symfony/blob/2.6/UPGRADE-2.6.md
Symfony 2.3.x
Untuk melakukannya di symfony 2.3 Anda tidak bisa lagi hanya mengatur token dalam konteks keamanan. Anda juga perlu menyimpan token ke sesi tersebut.
Dengan asumsi file keamanan dengan firewall seperti:
// app/config/security.yml
security:
firewalls:
main:
//firewall settings here
Dan tindakan pengontrol serupa juga:
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use YourNameSpace\UserBundle\Entity\User;
class LoginController extends Controller{
public function registerAction()
{
$user = //Handle getting or creating the user entity likely with a posted form
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.context')->setToken($token);
$this->get('session')->set('_security_main',serialize($token));
//Now you can redirect where ever you need and the user will be logged in
}
}
Untuk pembuatan token Anda akan ingin membuat UsernamePasswordToken
, Ini menerima 4 parameter: Entitas Pengguna, Kredensial Pengguna, Nama Firewall, Peran Pengguna. Anda tidak perlu memberikan kredensial pengguna agar token menjadi valid.
Saya tidak 100% yakin bahwa menyetel token pada security.context
diperlukan jika Anda hanya akan langsung mengalihkan. Tapi sepertinya tidak sakit jadi saya tinggalkan.
Kemudian bagian yang penting, pengaturan variabel sesi. Konvensi penamaan variabel _security_
diikuti dengan nama firewall Anda, dalam hal ini main
pembuatan_security_main
$this->get('session')->set('_security_main', serialize($token));
. Terima kasih, @Chausser!main
DAN Anda diautentikasi dengan firewall lain bernamaadmin
(karena Anda meniru pengguna), hal yang aneh terjadi: Anda_security_admin
mendapatkanUsernamePasswordToken
pengguna yang Anda berikan, yaitu Anda "terputus" dariadmin
firewall Anda . Ada ide bagaimana cara mempertahankan token untuk firewall "admin"?setToken(..)
bawah firewall target yang sama atau belum diautentikasi .Menemukan yang ini, akhirnya.
Setelah pendaftaran pengguna, Anda harus memiliki akses ke instance objek apa pun yang telah Anda tetapkan sebagai entitas pengguna Anda dalam konfigurasi penyedia Anda. Solusinya adalah membuat token baru dengan entitas pengguna tersebut dan meneruskannya ke konteks keamanan. Berikut adalah contoh berdasarkan penyiapan saya:
RegistrationController.php:
Dimana
main
nama firewall untuk aplikasi Anda (terima kasih, @Joe). Hanya itu yang ada di sana; sistem sekarang menganggap pengguna Anda masuk sepenuhnya sebagai pengguna yang baru saja mereka buat.EDIT: Sesuai komentar @ Miquel, saya telah memperbarui sampel kode pengontrol untuk menyertakan peran default yang masuk akal untuk pengguna baru (meskipun jelas ini dapat disesuaikan sesuai dengan kebutuhan spesifik aplikasi Anda).
sumber
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
Jika Anda memiliki objek UserInterface (dan seharusnya itu yang paling sering terjadi) Anda mungkin ingin menggunakan fungsi getRoles yang diimplementasikannya untuk argumen terakhir. Jadi jika Anda membuat fungsi logUser, akan terlihat seperti ini:
sumber
Saya menggunakan Symfony 2.2 dan pengalaman saya sedikit berbeda dari Problematic , jadi ini adalah versi gabungan dari semua info dari pertanyaan ini ditambah beberapa dari saya sendiri.
Saya pikir Joe salah tentang nilai
$providerKey
, parameter ketiga untukUsernamePasswordToken
konstruktor. Ini seharusnya menjadi kunci penyedia otentikasi (bukan pengguna). Ini digunakan oleh sistem otentikasi untuk membedakan antara token yang dibuat untuk penyedia yang berbeda. Penyedia apa pun yang turun dariUserAuthenticationProvider
hanya akan mengautentikasi token yang kunci penyedia cocok dengan miliknya sendiri. Misalnya,UsernamePasswordFormAuthenticationListener
set kunci dari token yang dibuatnya agar sesuai dengan yang terkaitDaoAuthenticationProvider
. Itu memungkinkan satu firewall memiliki beberapa penyedia nama pengguna + kata sandi tanpa mereka menginjak satu sama lain. Oleh karena itu, kami perlu memilih kunci yang tidak akan bertentangan dengan penyedia lain. Saya menggunakan'new_user'
.Saya memiliki beberapa sistem di bagian lain aplikasi saya yang bergantung pada peristiwa keberhasilan autentikasi , dan itu tidak diaktifkan hanya dengan menyetel token pada konteksnya. Saya harus mendapatkan
EventDispatcher
dari wadah dan mengaktifkan acara secara manual. Saya memutuskan untuk tidak mengaktifkan acara login interaktif karena kami mengautentikasi pengguna secara implisit, bukan sebagai tanggapan atas permintaan login eksplisit.Perhatikan bahwa penggunaan
$this->get( .. )
mengasumsikan cuplikan ada dalam metode pengontrol. Jika Anda menggunakan kode di tempat lain, Anda harus mengubahnya untuk dipanggilContainerInterface::get( ... )
dengan cara yang sesuai dengan lingkungan. Kebetulan entitas pengguna saya menerapkanUserInterface
sehingga saya dapat menggunakannya secara langsung dengan token. Jika milik Anda tidak, Anda harus menemukan cara untuk mengubahnya menjadiUserInterface
instance.Kode itu berfungsi, tetapi saya merasa seperti meretas arsitektur otentikasi Symfony daripada bekerja dengannya. Mungkin akan lebih tepat untuk mengimplementasikan penyedia otentikasi baru dengan kelas tokennya sendiri daripada membajak
UsernamePasswordToken
. Selain itu, menggunakan penyedia yang tepat berarti acara tersebut ditangani untuk Anda.sumber
Jika ada orang yang memiliki pertanyaan lanjutan yang sama yang membuat saya kembali ke sini:
Panggilan
hanya mempengaruhi arus
security.context
untuk rute yang digunakan.Yaitu Anda hanya dapat login pengguna dari url dalam kendali firewall.
(Tambahkan pengecualian untuk rute jika diperlukan -
IS_AUTHENTICATED_ANONYMOUSLY
)sumber
Dengan Symfony 4.4, Anda cukup melakukan hal berikut dalam metode pengontrol Anda (lihat dari dokumentasi Symfony: https://symfony.com/doc/current/security/guard_authentication.html#manually-authenticating-a-user ):
Satu hal penting, pastikan firewall Anda tidak disetel ke
lazy
. Jika ya, token tidak akan pernah disimpan dalam sesi dan Anda tidak akan pernah bisa masuk.sumber
Seperti Bermasalah di sini telah disebutkan, parameter $ providerKey yang sulit dipahami ini sebenarnya tidak lebih dari nama aturan firewall Anda, 'foobar' dalam contoh di bawah ini.
sumber
blablabla
sebagai parameter ketiga ke UsernamePasswordToken, itu akan berfungsi juga? apa arti parameter ini?Saya mencoba semua jawaban di sini dan tidak ada yang berhasil. Satu-satunya cara saya dapat mengotentikasi pengguna saya pada pengontrol adalah dengan membuat subrequest dan kemudian mengalihkan. Ini kode saya, saya menggunakan silex tetapi Anda dapat dengan mudah menyesuaikannya ke symfony2:
sumber
Pada Symfony versi 2.8.11 (mungkin berfungsi untuk versi yang lebih lama dan yang lebih baru), jika Anda menggunakan FOSUserBundle cukup lakukan ini:
Tidak perlu mengirimkan acara seperti yang pernah saya lihat di solusi lain.
terinspirasi dari FOS \ UserBundle \ Controller \ RegistrationController :: authenticateUser
(dari versi FOSUserBundle composer.json: "friendsofsymfony / user-bundle": "~ 1.3")
sumber