Setelah mencari di Web dan mencoba berbagai cara, inilah yang saya sarankan untuk otentikasi Java EE 6:
Siapkan bidang keamanan:
Dalam kasus saya, saya memiliki pengguna dalam database. Jadi saya mengikuti posting blog ini untuk membuat JDBC Realm yang dapat mengotentikasi pengguna berdasarkan nama pengguna dan kata sandi hash MD5 di tabel database saya:
http://blog.gamatam.com/2009/11/jdbc-realm-setup-with-glassfish-v3.html
Catatan: posting berbicara tentang pengguna dan tabel grup dalam database. Saya memiliki kelas Pengguna dengan atribut enum UserType yang dipetakan melalui anotasi javax.persistence ke database. Saya mengkonfigurasi ranah dengan tabel yang sama untuk pengguna dan grup, menggunakan kolom userType sebagai kolom grup dan itu berfungsi dengan baik.
Gunakan otentikasi formulir:
Masih mengikuti posting blog di atas, konfigurasikan web.xml dan sun-web.xml Anda, tetapi alih-alih menggunakan otentikasi BASIC, gunakan FORMULIR (sebenarnya, tidak masalah yang mana yang Anda gunakan, tapi saya akhirnya menggunakan FORMULIR). Gunakan HTML standar, bukan JSF.
Kemudian gunakan tip BalusC di atas tentang malas menginisialisasi informasi pengguna dari database. Dia menyarankan melakukannya dalam kacang yang dikelola mendapatkan kepala sekolah dari konteks wajah. Saya menggunakan kacang sesi stateful untuk menyimpan informasi sesi untuk setiap pengguna, jadi saya menyuntikkan konteks sesi:
@Resource
private SessionContext sessionContext;
Dengan kepala sekolah, saya dapat memeriksa nama pengguna dan, menggunakan EJB Entity Manager, mendapatkan informasi Pengguna dari database dan menyimpannya di SessionInformation
EJB saya .
Keluar:
Saya juga mencari-cari cara terbaik untuk keluar. Yang terbaik yang saya temukan menggunakan Servlet:
@WebServlet(name = "LogoutServlet", urlPatterns = {"/logout"})
public class LogoutServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession(false);
// Destroys the session for this user.
if (session != null)
session.invalidate();
// Redirects back to the initial page.
response.sendRedirect(request.getContextPath());
}
}
Meskipun jawaban saya benar-benar terlambat mengingat tanggal pertanyaan, saya harap ini membantu orang lain yang berakhir di sini dari Google, seperti yang saya lakukan.
Ciao,
Vítor Souza
HttpServletResponse#login(user, password)
, dengan cara itu Anda bisa mendapatkan dari DB garam pengguna, iterasi dan apa pun yang Anda gunakan untuk pengasinan, hash kata sandi yang dimasukkan pengguna menggunakan garam itu dan kemudian minta wadah untuk mengotentikasi denganHttpServletResponse#login(user, password)
.Saya kira Anda ingin otentikasi berbasis formulir menggunakan deskriptor penyebaran dan
j_security_check
.Anda juga dapat melakukan ini di JSF hanya dengan menggunakan nama bidang
j_username
danj_password
seperti yang ditunjukkan dalam tutorial.Misalnya
Anda dapat melakukan pemuatan malas di
User
pengambil untuk memeriksa apakahUser
sudah masuk dan jika tidak, lalu periksa apakahPrincipal
ada dalam permintaan dan jika demikian, maka dapatkan yangUser
terkait dengannyaj_username
.The
User
jelas diakses di JSF EL oleh#{auth.user}
.Untuk keluar, lakukan a
HttpServletRequest#logout()
(dan setelUser
ke nol!). Anda bisa mendapatkan peganganHttpServletRequest
di JSF denganExternalContext#getRequest()
. Anda juga dapat membatalkan sesi secara keseluruhan.Untuk yang tersisa (mendefinisikan pengguna, peran, dan kendala dalam penerapan descriptor dan ranah), cukup ikuti tutorial Java EE 6 dan dokumentasi servletcontainer dengan cara biasa.
Pembaruan : Anda juga dapat menggunakan Servlet 3.0 baru
HttpServletRequest#login()
untuk melakukan login terprogram alih-alih menggunakanj_security_check
yang mungkin tidak dapat dijangkau oleh operator di beberapa server servlet. Dalam hal ini, Anda bisa menggunakan formulir JSF yang layak dan kacang denganusername
danpassword
properti danlogin
metode yang terlihat seperti ini:Dan tampilan ini mencakup kacang yang dikelola yang juga mengingat halaman yang awalnya diminta:
Dengan cara
User
ini dapat diakses di JSF EL oleh#{user}
.sumber
j_security_check
mungkin tidak berfungsi pada semua servletcontainers.@WebServlet(name="testServlet", urlPatterns={"/ testServlet "}) @ServletSecurity(@HttpConstraint(rolesAllowed = {"testUser", "admin”}))
Dan pada metode per level:@ServletSecurity(httpMethodConstraints={ @HttpMethodConstraint("GET"), @HttpMethodConstraint(value="POST", rolesAllowed={"testUser"})})
FacesServlet
dan Anda tidak bisa (dan tidak mau) memodifikasinya.RequestDispatcher.FORWARD_REQUEST_URI
. Atribut permintaan tersedia di JSF olehExternalContext#getRequestMap()
.Harus disebutkan bahwa ini adalah opsi untuk sepenuhnya meninggalkan masalah otentikasi ke pengontrol depan, misalnya Apache Webserver dan mengevaluasi HttpServletRequest.getRemoteUser () sebagai gantinya, yang merupakan representasi JAVA untuk variabel lingkungan REMOTE_USER. Ini juga memungkinkan desain log in yang canggih seperti otentikasi Shibboleth. Memfilter Permintaan ke wadah servlet melalui server web adalah desain yang baik untuk lingkungan produksi, sering mod_jk digunakan untuk melakukannya.
sumber
Masalah HttpServletRequest.login tidak mengatur status otentikasi dalam sesi telah diperbaiki di 3.0.1. Perbarui glassfish ke versi terbaru dan Anda selesai.
Memperbarui cukup mudah:
sumber