Простые возможности входа и выхода из системы для моего веб-приложения (JSF 2.0)

#java #security #authentication #jsf-2 #ejb-3.0

#java #Безопасность #аутентификация #jsf-2 #ejb-3.0

Вопрос:

Этим утром я изучил главы 39,40 и 41 руководства JEE6. Но я очень, очень смущен. У меня нет опыта работы с безопасностью веб-приложений с JEE6, и у меня возникают большие трудности с пониманием и внедрением.

Мне нужно создать механизм авторизации для моего веб-приложения, мой сценарий также не очень прост для новичка в JEE6 вроде меня, поэтому я решил попытаться найти самый простой способ сделать это.

Я подумал объяснить свою идею, чтобы вы могли поправить меня и дать мне несколько советов о том, как это было бы наилучшим и простым способом сделать это.

Идея:

Мое веб-приложение использует компонент primefaces под названием dock, который выводит диалоговое окно входа при нажатии кнопки use на последнем элементе. Также этот инструмент навигации расположен в шаблоне JSF, который используется всеми другими страницами приложения.

     <h:body>
<p:dock position="top"> 
    <p:menuitem value="Naslovna" icon="unsecuredimages/naslovna.png" url="main.xhtml"
        alt="The image could not be found." />
    <p:menuitem value="Register" icon="unsecuredimages/register.png"
        url="registration.xhtml" alt="The image could not be found." />
    <p:menuitem value="Cesta pitanja" icon="unsecuredimages/faq.png"
        url="faq.xhtml" alt="The image could not be found." />
        <!-- The login will not have a page, it will pop up a login dialog -->
    <p:menuitem value="Login" icon="unsecuredimages/login.png" url="#" onclick="dlg.show()"/>       
</p:dock>
<p:dialog header="Prijavite se" widgetVar="dlg"  modal="true" draggable="false" resizable="false" effect="SLIDE">  
     <h:outputText value="Em@il:" /><h:inputText id="email" value=""/>
     <br/>  
     <h:outputText value="Lozinka:" /><h:inputText id="password" value=""/>
     <br/> 
     <h:commandButton value="Prijavi se" />
</p:dialog>     
    <br/><br/><br/><br/><br/><br/>  
<ui:insert name="mainForm" />
<ui:insert name="registrationForm" />
<ui:insert name="registrationBuyerForm" />
<ui:insert name="registrationSellerForm" />
<ui:insert name="faqForm" />
<ui:insert name="registrationSuccessForm" />
  </h:body>
  

Я думаю, что в этом JSF должен быть вспомогательный компонент, который обрабатывает электронную почту и пароль для EJB.

 import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import ejbinterfaces.IAuthentificationEJB;
@ManagedBean
@SessionScoped
public class SecurityController {
@EJB
private IAuthentificationEJB authentificationEJB;
private String email;
private String password;

public void logIn() {
    authentificationEJB.saveUserState(email, password);
}

public String getEmail() {
    return email;
}

public String getPassword() {
    return password;
}

public void setEmail(String email) {
    this.email = email;
}

public void setPassword(String password) {
    this.password = password;
}   
  

}

Затем EJB должен выполнить вход в систему и выйти из системы (вот тут я сильно запутался):

 @Stateful(name = "ejbs/AuthentificationEJB")
public class AuthentificationEJB implements IAuthentificationEJB {      
//Login
public boolean saveUserState(String email,String password) {
    //1-Send query to database to see if that user exist
    //2-If the query returns the user object, store it somewhere in the session(HOW?)
    //3-return true if the user state was saved
    //4-return false otherwise
    return false;
}


//Logout
public void releaseUserState() {
    //1-Check if there is something saved in the session(or wherever the state is saved)
    //2-If 1 then flush it
}

//Check if user is logged in
public boolean checkAuthentificationStatus() {
    //1-Check if there is something saved in the session(This means the user is logged in)
    //2-If there is not a user already loged, then return false
    return false;
}
  

}

Я решил не использовать область jdbc или другие механизмы аутентификации, описанные в руководстве JEE6, потому что я действительно запутываюсь, поэтому я думаю, что сейчас мне проще сделать это вручную. У меня есть некоторые сомнения по поводу моего подхода:

  • Правильный ли этот подход (можно ли это сделать таким образом)?
  • Должен ли EJB быть @Stateless или @Statefull в этом случае (пользователь, повторно загруженный из базы данных, имеет только 2 строковых поля)?
  • Где я должен хранить идентификатор извлеченного пользователя из базы данных, чтобы он сохранялся до тех пор, пока пользователь не решит выйти из системы?

  • Если мне нужно сохранить состояние пользователя в сеансе, пока он / она не решит выйти из системы, как я могу это сделать?

  • При таком подходе сеанс для пользователя будет удален при закрытии браузера без выхода из системы (если нет, как я могу автоматически завершить его / ее сеанс через некоторое время, если нет активности?)

Я буду очень признателен за вашу помощь.

Комментарии:

1. Здесь я не рассматриваю вашу проблему, но я рекомендую вам попробовать использовать контейнерный подход к обеспечению безопасности и позволить им управлять этим (в конце концов, для этого существуют фреймворки). Для вас). Если у вас возникли проблемы с настройкой области jdbc, есть одна область, которую можно настроить для чтения файла свойств, который довольно прост в настройке.

Ответ №1:

Некоторые части головоломки:

Правильный ли этот подход (можно ли это сделать таким образом)?

Да, это возможно. Вы можете выбирать между безопасностью, управляемой контейнером, или безопасностью, управляемой приложением.

Должен ли EJB быть @Stateless или @Statefull в этом случае (пользователь, повторно загруженный из базы данных, имеет только 2 строковых поля)?

Если вы сохраняете идентификатор текущего вошедшего в систему пользователя в контексте сеанса (см. Ниже), я думаю, вы можете сделать это с помощью компонента без состояния (из теории).

Где я должен хранить идентификатор извлеченного пользователя из базы данных, чтобы он сохранялся до тех пор, пока пользователь не решит выйти из системы?

Вы можете сохранить его в контексте сеанса:

 FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("userID", email);
  

Используйте getSessionMap()#get("userID") для проверки сохраненного идентификатора пользователя.

При таком подходе сеанс для пользователя будет удален при закрытии браузера без выхода из системы (если нет, как я могу автоматически завершить его / ее сеанс через некоторое время, если нет активности?)

Нет, сеанс автоматически завершается по истечении времени ожидания. Время ожидания может быть установлено в вашем web.xml:

 <session-config>
   <session-timeout>60</session-timeout>
</session-config>
  

Этот параметр означает, что время ожидания сеансов истекает после 60 минут бездействия сервера.

Комментарии:

1. Это был полезный ответ, спасибо. Я начну внедрять аутентификацию, управляемую моим приложением, сегодня. У меня просто есть еще одно небольшое сомнение относительно времени ожидания. Если я установлю время ожидания на 60, будет ли пользователь автоматически выходить из системы, даже если он / она в данный момент использует приложение, или время ожидания начнет отсчитываться при наличии innactivity?

2. Правильным было бы бездействие сервера . Время ожидания начинается с момента последнего подключения сервера. Однажды у меня была очень длинная форма без ajax, и пользователь не смог заполнить ее в течение 60 минут, и сеанс истек…

3. Я вижу, это хорошо, мне не нужно беспокоиться об этом, если сеанс истечет, это будет ошибка пользователей. Ему придется войти в систему снова 🙂 Вы упомянули форму без ajax, я не понимаю, почему ajax будет иметь значение в отношении времени ожидания сеанса?

4. Инструкции Ajax обычно запускают (частичные) запросы к серверу.