GWT EJB - Logowanie, Sesja, Hashowanie

0

Hej, umie ktoś udzielić pomocy jak wykonać w GWT lub GWT-P ekran logowania?

Mam kilka pytań.

  1. Gdzie hashować? Widok, Presenter, DAO,?
  2. Czym hashować?
  3. Jak wykorzystać EJB do trzymania sesji?
    Może jakiś przykład?
    W tej chwili mam przygotowana komunikacje z serwerem i chciałbym wiedzieć jak zrobić EJB trzymającego sesję?
0

Jeśli chcesz korzystać z GWT jako podstawy to polecam zapoznać się z Vaadinem - który o niebo uprzyjemnia życie i pozwala też na pisanie własnych rzeczy w GWT. Dodatkowo masz tam już wszystko niezbędne do ejb czy springa.

0

Dokładniej używam GWTP, mam ogólnie problem jak przy pomocy ejb zrobić logowanie. Nie robiłem tego nigdy nie mam nawet pomysłu czy to powinno być po stronie klienta czy serwera... znalazłem na necie taki kod ale za bardzo go nie ogarniam...

public class ServiceImpl extends RemoteServiceServlet implements Service  
{
   void CreateSession(String Username)
   {
      HttpServletRequest request = this.getThreadLocalRequest();
      HttpSession session = request.getSession();
      session.setAttribute("Username", Username);
   }

   boolean ValidateSession(String Username)
   {
       HttpServletRequest request = this.getThreadLocalRequest();
       HttpSession session = request.getSession();
       if (session.getAttribute("Username"))
       {
          return true;
       }
       return false;
   }
}

Równie dobrze używając ejb i swing też miałbym problem to zrobić, więc problemem nie jest technologia a idea algorytmu tak mi się wydaje.

1

Hmm co ci mogę powiedzieć, zobacz jak działa protokół http i z czego się ogólnie składa. Sama walidacja powinna być robiona po stronie servera(który traktujemy jako bezpieczny), strona klienta jest niebezpieczna(np. taki javaScript możesz sobie podmienić na bieżąco) także ogólnie zasada jest taka: client wysyła dane do logowania na serwer, na serwerze sprawdzasz czy te dane są poprawne(validate), i jeśli tak, to np. w EJB(po stronie serwera) do obiektu sesyjnego wrzucasz że dany użytkownik jest uwierzytelniony i dajesz mu dostęp do inny stron. Inaczej przy próbie wejścia na inną stronę niż logowania powinien być przeniesiony na stronę logownaia. Ogólnie jeśli nie znasz się na tego typu systemach i/albo nie znasz dobrze javy to odradzam działanie na GWT(on się rządzi często swoimi prawami). Zobacz czy nie zainteresuje ciebie Vaadin albo najlepiej ogarnij sobie podstawy servletów lub od razu uderz w SpringMVC

0

Fajnie to opisałeś. Mógłbym prosić o przykład który opisze ten fragment twojej wypowiedzi:

" EJB(po stronie serwera) do obiektu sesyjnego wrzucasz że dany użytkownik jest uwierzytelniony i dajesz mu dostęp do inny stron"

Jak zrobić to co zacytowałem? jakich klas użyć? Jakich adnotacji w sesyjnym EJB? Bo to jest właśnie etap na którym utknąłem:D

0

Ja w Vaadinie robiłem to przy użyciu EJB i CDI bo się fajnie uzupełniają. W samym EJB masz tak naprawdę albo singleton albo bezstanowy obiekt. Nie wiem też w jaki sposób przejmujesz żądanie klienta ale ogólnie chodzi o to że do obiektu sesyjnego HttpSession (który jest zwykłym obiektem):

 HttpSession session = request.getSession();

wrzucasz:

 session.setAttribute("isLogin", true);

a jak masz główną klasę przechwytującą(powinna być w EJB) to sprawdzasz czy użytkownik jest zalogowany, jeśli nie to przenosisz go na strone logowania o ile dany url to nie jest już strona logowania. A jeśli jest zalogowany to pokazujesz mu treść właściwą strony. I to musisz robić dla każdego wywołania. Np.

 if (session.getAttribute("isLogin") == false && currentSite != loginSite)
 {
    goToSite(loginSite);
}
else{
    viewCurrentSite(currentSite)
}

A to jak już zrobisz logikę to w sumie odrębny temat.

0

Do komunikacji client-server używam RESTów
Czyli ten cały kod który podałeś powinien być w bean?

To co zrobiłem

@Singleton
public class LogowanieSesja extends RemoteServiceServlet {

	public PracownikDTO pobierzZalogowanegoPracownika() {
		return (PracownikDTO) getThreadLocalRequest().getSession().getAttribute("aktualny_pracownik");
	}

	public void uruchomSesje(PracownikDTO pracownikDTO) {
		getThreadLocalRequest().getSession().setAttribute("aktualny_pracownik", pracownikDTO);
	}

	public PracownikDTO zaloguj(String login, String password) {

		PracownikDTO pracownikDTO = new PracownikDTO();
		if (true) {
			//if bedzie uzupelniony
			// mechanizm sprawdzający czy zalogowany
			uruchomSesje(pracownikDTO);
		}

		else {
			pracownikDTO = null;
		}

		return pracownikDTO;

	}

}
0

Ja napiszę jak to się robi "standardowo" w JavaEE. Mianowicie konfiguruje się tzw. realm, który chyba można nazwać "sposobem uwierzytelniania", bo jest np. jdbcRealm (oparty o bazę danych), ldapRealm (oparty o LDAP), czy CertificateRealm oparty o certyfikaty. Ten realm konfiguruje się po stronie serwera aplikacyjnego. Użytkownika loguje się metodą login klasy HttpServletRequest, dzięki czemu później możemy korzystać z tzw. "propagacji tożsamości użytkownika". W klasach EJB możesz pobrać zalogowanego użytkownika za pomocą metody SessionContext::getCallerPrincipal, a w warstwie web jest dostępny poprzez HttpServletRequest::getUserPrincipal(). Standardowo w JavaEE autoryzacja działa na zasacie RBAC, ograniczenia dostępu na EJB nakłada się adnotacjami @RolesAllowed.

0

Gdzie powinienem użyc klasy HttpServletRequest? view/presenter/rest/ejb?

0

Jak używasz komunikacji po REST to zobacz sobie na Spring Boot tam jest to fajnie zrobione walisz klasę rozruchową a potem

@RestController 

i wyprowadzasz usługi. Najprostszy system logowania możesz zrobić na czasowych tokenach a potem podmienisz to pod np. Spring Security.

0

Poczytam Panowie/Panie to co wysłaliście.

Mam coś podobnego: i przy restach wygląda to tak:

server

@ApplicationPath("/cos")
public class RestStarter extends Application{

}

i to np:

@Path("/Pracownik")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class PracownikResourceImpl  {

	@EJB
	PracownikDAO pracownikDAO;

	@POST
	@Path("/dodajPracownika")
	public void dodajPracownika(PracownikDTO pracownikDTO) {
		pracownikDAO.dodajPracownika(pracownikDTO.stworzPracownika());

	}

a w shared czyli po stronie klienta:

@Path("/Pracownik")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public interface PracownikResource {

	@POST
	@Path("/dodajPracownika")
	public RestAction<Void> dodajPracownika(PracownikDTO pracownikDTO);

a w kliencie mam tak:

private void dodajDoBazy(final PracownikDTO pracownikDTO) {
		dispatcher.execute(pracownikResource.dodajPracownika(pracownikDTO), new AsyncCallback<Void>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("COS NIE DZIAŁA - DODAJ PRACOWNIKA");
			}

			@Override
			public void onSuccess(Void result) {
				Window.alert("DODANO!");
				funkcjaDoFireEvent();
			}
		});
	}

a ejb:

@Stateless
public class PracownikDAO {
	
	@PersistenceContext(unitName = "postgres")
	private EntityManager entityManager;
	
	public void dodajPracownika(Pracownik pracownik){
		entityManager.persist(pracownik);
	}

I chciałbym analogicznie zrobic sesje + logowanie

0

REST jest bezstanowy, ale możesz przechowywać sesje np. w bazie danych albo pamięci operacyjnej czyli np. zrobić

 Map<String, SessionObject>

. Po rest wystawiasz opcje logowania: (login, hasło) w odpowiedzi otrzymujesz wygenerowany ciąg unikatowych znaków. Pod ten ciąg w serwerze tworzysz obiekt sesyjny i dodajesz do Mapy. Następnie podczas wywoływania jakiś usług w nagłówku albo w body requesta wysyłasz dany ciąg znaków i na podstawie tego uzyskujesz dostęp do obiektu sesyjnego na serwerze.

0

Jak używając restów uzyskać dostęp do requesta? bo w servlecie to widać jasno a w rest jakoś chyba tego nie bardzo widać jak dla mnie;/

1
@POST
public Response postSomething(@QueryParam("name") String name, @Context UriInfo uriInfo, String content) {
     MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(); 
     String nameParam = queryParams.getFirst("name");
}
0

Dzięki za każde info co tu dajecie. jutro podziergam i zobaczę co z tego wyjdzie:) Mam nadzieję że się uda.

0

Nie mogę dać jako return response z paczki: import javax.ws.rs.core.Response; bo wywala mi błąd następujący:

"Unable to create or inherit binding: No @Inject or default constructor found for"

EDIT*

Problem rozwiązałem chyba...

Używam ciasteczek z pakietu: ** import com.google.gwt.user.client.Cookies**;

na onSuccess (czyli po potwierdzeniu ze taki user istnieje) dodaje ciasteczko o nazwie login i wartości tego login i operuje na nim. Nie bardzo wiem jak ustawić cykl życia tego ciasteczka ale to poszukam.

Pytanie 2 z tytułu tego postu. Czym hashować?

I jeszcze jedno odnośnie forum... Czemu tekst mi się nie pogrubia czasem? -,-

1 użytkowników online, w tym zalogowanych: 0, gości: 1