#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 обычно запускают (частичные) запросы к серверу.