Uważam, że program operacyjny nie ma obecnie zastosowania. Niemniej jednak zasługuje na kompleksową odpowiedź. W rzeczywistości jestem zaskoczony, że jeszcze go nie ma.
Po pierwsze, jest to zły pomysł: taki układ, jak zaproponowany przez PO, jest naprawdę zbyt niepewny. Niemniej jednak rozwiązanie opisanego problemu może być dobrym prototypem dla kogoś, kto tworzy autologię dla Liferay.
Teraz powiedzmy, że chcesz automatycznie logować się do dowolnego użytkownika, którego nazwa jest wysyłana w parametrze ciągu zapytania. Na przykład, jeśli jeden dostęp to http://localhost:8080/web/guest/home?insecurely_login_user=juju
, to należy zalogować się do Liferay użytkownika juju
. Jak to zrobić? Wykonaj czynności opisane poniżej:
Tworzenie klasy automatycznego logowania
Po pierwsze, stworzenie wtyczki haka. W katalogu docroot/WEB-INF/src
tworzy klasę implementującą interfejs com.liferay.portal.security.auth.AutoLogin
. W moim przykładzie będę go nazywać br.brandizzi.adam.liferay.insecure.InsecureAutoLogin
.
Interfejs AutoLogin
ma tylko jeden sposób, zwany login()
, który oczekuje dwa parametry (e HttpServletRequest
i an HttpServletResponse
wystąpienia) i zwraca szereg strun.Tak, moja klasa będzie wyglądać bez realizacji:
public class InsecureAutoLogin implements AutoLogin {
@Override
public String[] login(HttpServletRequest request,
HttpServletResponse response) throws AutoLoginException {
// TODO Auto-generated method stub
return null;
}
}
Sposób AutoLogin.login()
postara się odzyskać informacje niezbędne do uwierzytelnienia z wielu źródeł, głównie obiektu żądania. Jeśli zdecyduje, że użytkownik powinien być zalogowany, zwraca tablicę z odpowiednimi danymi do uwierzytelnienia; jeśli zdecyduje się na , nie zaloguj użytkownika, może po prostu zwrócić null
.
W naszym przypadku staramy się uzyskać nazwę użytkownika z parametru insecurely_login_user
z żądania. Jeśli jest taki parametr, będziemy kontynuować logowanie; jeśli nie ma takiego parametru, to po prostu zwraca null
:
String screenName = request.getParameter("insecurely_login_user");
if (screenName == null || screenName.isEmpty()) {
return null;
}
Więc mamy pseudonim. Co zrobić teraz? Pozwól nam pobrać użytkownika z bazy danych o tej samej nazwie ekranowej.
long companyId = PortalUtil.getCompanyId(request);
User user = UserLocalServiceUtil.getUserByScreenName(companyId,
screenName);
Jeśli wich użytkownik taki pseudonim istnieje, zostanie ona pobrana i przypisana do zmiennej user
. W takim przypadku uwierzytelnianie powinno zakończyć się sukcesem, a klasa autologin powinna zwrócić tablicę trzech ciągów znaków - poświadczeń. Są to wartości, które mają być zwrócone jako poświadczeń, w celu zamieszczenia ich w tablicy:
- identyfikator użytkownika jako ciąg
- hasło użytkownika, które mogą być szyfrowane, czy nie;
- Wartość boolowska, rzutowana na ciąg, wskazująca, czy hasło jest zaszyfrowane.
Więc tutaj jest linia:
return new String[] {
String.valueOf(user.getUserId()),
user.getPassword(),
String.valueOf(user.isPasswordEncrypted())
};
Jeśli użytkownik nie znajduje jednak wyjątek zostanie rzucony. Tak więc, musimy otoczyć powyższy kod konstrukcją try
/catch
. Jeśli jest wyjątek, tylko wrócić null
:
try {
long companyId = PortalUtil.getCompanyId(request);
User user = UserLocalServiceUtil.getUserByScreenName(companyId,
screenName);
return new String[] { String.valueOf(user.getUserId()),
user.getPassword(),
String.valueOf(user.isPasswordEncrypted()) };
} catch (Exception e) {
return null;
}
W końcu to moja InsecureAutoLogin
klasa:
public class InsecureAutoLogin implements AutoLogin {
public String[] login(HttpServletRequest request,
HttpServletResponse response) throws AutoLoginException {
String screenName = request.getParameter("insecurely_login_user");
if (screenName == null || screenName.isEmpty())
return null;
try {
long companyId = PortalUtil.getCompanyId(request);
User user = UserLocalServiceUtil.getUserByScreenName(companyId,
screenName);
return new String[] { String.valueOf(user.getUserId()),
user.getPassword(),
String.valueOf(user.isPasswordEncrypted()) };
} catch (Exception e) {
return null;
}
}
}
Rejestrowanie klasy automatycznego logowania
Teraz nasz hak powinien zarejestrować tę klasę jako procesor autologin. To naprawdę łatwe.
pierwsze, edytować plik docroot/WEB-INF/liferay-hook.xml
dodanie elementu portal-properties
z wartością portal.properties
:
<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_1_0.dtd">
<hook>
<portal-properties>portal.properties</portal-properties>
</hook>
Teraz utwórz plik o nazwie portal.properties
na docroot/WEB-INF/src
. Powinna ona zawierać właściwość o nazwie auto.login.hooks
którego wartość powinna być nazwa naszej klasy:
auto.login.hooks=br.brandizzi.adam.liferay.insecure.InsecureAutoLogin
I to jest to. Rozmieść ten hak i twój autologin będzie działał.
Wnioski
Jak już mówiłem, to nie powinien używać takiego niebezpiecznego „autoryzacja” metody. Zbyt łatwo jest go ominąć, uzyskując nawet uprawnienia administracyjne! Jeśli jednak wykonasz te kroki, masz szkielet, aby stworzyć lepszą funkcję autologin. Ponadto, wiem, że niektórzy ludzie chcą, abychcieli zrobić coś takiego jak ta niezabezpieczona metoda "uwierzytelniania" i czasami musimy zawiesić nasze sądy i pomóc strzelić sobie w nogi ...
Kod źródłowy tego projektu może można znaleźć here i można pobrać WAR here.
Chcę, aby zalogować się użytkownikowi automatycznie kiedy kliknie link, bez niego konieczności podawania nazwy użytkownika i hasła . Nazwa i hasło są zapisywane w naszej bazie danych aplikacji. – Luke
Chociaż nie wiem, dlaczego ktoś chciałby to zrobić: można sprawdzić przykładową aplikację LR, która ma ten mechanizm jako demonstrację ("zaloguj się jako Bruno" itp.). Poza tym, zdecydowanie zaleciłbym użycie czegoś takiego jak OpenID lub CAS, aby zminimalizować wysiłek logowania użytkowników, ale nadal utrzymywać pewien poziom bezpieczeństwa. – Dirk
uzgodnione: Przejdź z dowolnym systemem pojedynczego logowania (np. CAS), aby użytkownicy uwierzytelniali się tylko raz (lub jeśli nalegasz, używaj NTLM) i ta tożsamość zostanie przekazana do aplikacji. Rozwiązania takie jak login Bruno mają być dla demo, a nie dla produkcji. Równie dobrze możesz dać anonimowemu użytkownikowi-gościowi więcej uprawnień, więc nie musisz się logować, jeśli rozważasz takie rozwiązanie. –