Po przeszukaniu sieci i wypróbowaniu wielu różnych sposobów, oto co zasugerowałbym dla uwierzytelniania Java EE 6:
Skonfiguruj dziedzinę zabezpieczeń:
W moim przypadku miałem użytkowników w bazie danych. Więc podążyłem za tym postem na blogu, aby utworzyć JDBC Realm, który może uwierzytelniać użytkowników na podstawie nazwy użytkownika i haszowanych haseł MD5 w mojej tabeli bazy danych:
http://blog.gamatam.com/2009/11/jdbc-realm-setup-with-glassfish-v3.html
Uwaga: post mówi o użytkowniku i tabeli grupowej w bazie danych. Miałem klasę użytkownika z atrybutem wyliczenia UserType zmapowanym za pośrednictwem adnotacji javax.persistence do bazy danych. Skonfigurowałem dziedzinę z tą samą tabelą dla użytkowników i grup, używając kolumny userType jako kolumny grupy i działało dobrze.
Użyj uwierzytelniania formularza:
Nadal postępując zgodnie z powyższym wpisem na blogu, skonfiguruj swoje pliki web.xml i sun-web.xml, ale zamiast używać uwierzytelniania BASIC, użyj FORMULARZA (właściwie nie ma znaczenia, którego używasz, ale ostatecznie użyłem FORMULARZA). Użyj standardowego kodu HTML, a nie JSF.
Następnie użyj powyższej wskazówki BalusC dotyczącej leniwego inicjowania informacji o użytkowniku z bazy danych. Zasugerował zrobienie tego w zarządzanej fasoli, uzyskując dyrektora z kontekstu twarzy. Zamiast tego użyłem stanowego komponentu bean sesji do przechowywania informacji o sesji dla każdego użytkownika, więc wstrzyknąłem kontekst sesji:
@Resource
private SessionContext sessionContext;
Z podmiotem głównym mogę sprawdzić nazwę użytkownika i za pomocą EJB Entity Manager pobrać informacje o użytkowniku z bazy danych i przechowywać w moim SessionInformation
EJB.
Wyloguj:
Rozejrzałem się też za najlepszym sposobem wylogowania. Najlepsze, jakie znalazłem, to użycie serwletu:
@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());
}
}
Chociaż moja odpowiedź jest naprawdę spóźniona, biorąc pod uwagę datę pytania, mam nadzieję, że pomoże to innym osobom, które trafiają tutaj z Google, tak jak ja.
Cześć,
Vítor Souza
HttpServletResponse#login(user, password)
, w ten sposób możesz po prostu pobrać z DB sól użytkownika, iteracje i cokolwiek, czego używasz do solenia, zaszyfrować hasło wprowadzone przez użytkownika za pomocą tej soli, a następnie poprosić kontener o uwierzytelnienieHttpServletResponse#login(user, password)
.Przypuszczam, że chcesz uwierzytelniać oparte na formularzach przy użyciu deskryptorów wdrażania i
j_security_check
.Można również zrobić to w JSF tylko przy użyciu tych samych predefinied nazwy pól
j_username
ij_password
jak wykazano w samouczku.Na przykład
Możesz wykonać leniwe ładowanie w
User
getterze, aby sprawdzić, czyUser
jest już zalogowany, a jeśli nie, to sprawdź, czyPrincipal
jest obecny w żądaniu, a jeśli tak, to pobierzUser
skojarzony zj_username
.User
Jest oczywiście dostępny w JSF EL przez#{auth.user}
.Aby się wylogować, wykonaj a
HttpServletRequest#logout()
(i ustawUser
na null!). Możesz uzyskać uchwytHttpServletRequest
w JSF przezExternalContext#getRequest()
. Możesz także całkowicie unieważnić sesję.Jeśli chodzi o resztę (definiowanie użytkowników, ról i ograniczeń w deskryptorze wdrażania i dziedzinie), po prostu postępuj zgodnie z samouczkiem Java EE 6 i dokumentacją servletcontainer w zwykły sposób.
Aktualizacja : możesz także użyć nowego Servlet 3.0
HttpServletRequest#login()
do automatycznego logowania zamiast używania,j_security_check
które samo w sobie może nie być osiągalne dla dyspozytora w niektórych kontenerach serwletów. W tym przypadku można użyć fullworthy formularza JSF i fasoli zusername
orazpassword
właściwości ilogin
metody, które wyglądają tak:I ten zarządzany komponent bean z zakresem widoku, który również pamięta początkowo żądaną stronę:
W ten sposób
User
plik jest dostępny w JSF EL przez#{user}
.źródło
j_security_check
dodając zastrzeżenie, że wysyłanie do może nie działać na wszystkich kontenerach serwletów.@WebServlet(name="testServlet", urlPatterns={"/ testServlet "}) @ServletSecurity(@HttpConstraint(rolesAllowed = {"testUser", "admin”}))
I na metodę według poziom:@ServletSecurity(httpMethodConstraints={ @HttpMethodConstraint("GET"), @HttpMethodConstraint(value="POST", rolesAllowed={"testUser"})})
FacesServlet
nie możesz (i nie chcesz) modyfikować.RequestDispatcher.FORWARD_REQUEST_URI
. Atrybuty żądania są w formacie JSF dostępne przezExternalContext#getRequestMap()
.Należy wspomnieć, że jest to opcja, aby całkowicie pozostawić kwestie uwierzytelniania kontrolerowi frontowemu, np. Serwerowi WWW Apache i zamiast tego ocenić HttpServletRequest.getRemoteUser (), która jest reprezentacją JAVA dla zmiennej środowiskowej REMOTE_USER. Pozwala to również na zaawansowane projekty logowania, takie jak uwierzytelnianie Shibboleth. Filtrowanie żądań do kontenera serwletów przez serwer WWW jest dobrym rozwiązaniem dla środowisk produkcyjnych, często do tego celu używa się mod_jk.
źródło
Problem HttpServletRequest.login nie ustawia stanu uwierzytelniania w sesji został rozwiązany w wersji 3.0.1. Zaktualizuj Glassfish do najnowszej wersji i gotowe.
Aktualizacja jest dość prosta:
źródło