Этот вопрос является продолжением here.Как установить UserBean при использовании JSF 2.0, CDI, EJB 3.1 Servlet Spec 3.0 Программная безопасность
При входе в систему мое приложение должно проконсультироваться с контейнером для аутентификации с помощью request.login(), а затем установить «Пользовательский» компонент, который содержит имя пользователя, пароль, роль и поле для определения местоположения. После успешной авторизации против контейнера (WAS 8) необходимо проверить роль пользователя, чтобы определить подходящую страницу приветствия, на которой пользователь должен быть перенаправлен. Мой контейнер реализует федеративный репозиторий, который в основном объединяет 3 ветви LDAP, базу данных и плоский файл. Существует много ролей (5 на данный момент, вероятно, будет более поздним).
У меня есть 2 beans: компонент RequestScoped Credentials и SessionScoped bean с именем Login. Вход содержит метод login(). У меня проблема с методом входа в систему.
Моя проблема заключается в том, что всякий раз, когда я использую:
Principal userPrincipal = request.getUserPrincipal();
request.getUserPrincipal();
if (userPrincipal != null) {
request.logout();
}
request.login(credentials.getUsername(), credentials.getPassword());
String name = userPrincipal.getName();
перед:
Donor donor = loginService.getDonor(credentials.getUsername());
currentUser = new Users();
currentUser.setLocation(donor.getCenter().getCity());
currentUser.setRole("DONOR");
currentUser.setUserId(credentials.getUsername());
currentUser.setFirstName(donor.getFirstName());
currentUser.setLastName(donor.getLastName());
currentUser.setUsername(credentials.getUsername());
currentUser.setName(credentials.getUsername());
return "users?faces-redirect=true";
мой боб CurrentUser Пользователь не хранится в сессии.
Я удалил первый фрагмент кода и заметил, что информация моего пользователя bean затем сохраняется в сеансе и может быть просмотрена на последующей странице пользователей. Я вернул первый кусок кода за строкой и заметил, что:
if (userPrincipal != null) {
request.logout();
}
вызывает проблему.
Как я должен хранить пользовательский компонент, реализующий программную безопасность и JSF2.0/CDI? Я провел недели на этом. Я могу представить себе что-то более сложное, как фильтр, который ловит перенаправление, захватывает пользовательский интерфейс, вызывает db или ldap для дополнительных атрибутов, а затем перенаправляется на соответствующую страницу ... но я хочу, чтобы все было просто. Там должен быть простой способ сделать это.
Первоначально я попробовал свою руку при входе в систему с помощью j_security_check и указав FORM в web.xml. Теперь, используя форму JSF 2.0 и метод входа в систему, я заметил, что FORM игнорируется в пользу BASIC. System.out.println ("getAuthType? .." + request.getAuthType()); возвращает «BASIC» в методе входа. Это приводит к раздражающему кешу, поэтому требуется request.logout. В противном случае request.login не удастся.
Вчера вечером я наткнулся на this, в котором содержится ссылка на here. Таким образом, может быть способ получить userprincipal, установить пользовательский компонент и перенаправить на соответствующую страницу приветствия. Я не знаю, как устарела эта 2-я ссылка. Также представляется, что j_security_check нельзя использовать в тандеме с программным средством определения, на какой странице я должен перенаправить пользователя на роль.
Что касается использования j_security_check или программной безопасности/JSF/CDI, мне просто нужно выяснить, что-то простое, и позволяет мне хранить логический элемент входа или независимый пользовательский компонент в сеансе.
Вот мой Логин форма с моей точки зрения:
<h:form id="loginForm">
<fieldset>
<div class="form-row">
<h:outputLabel for="username" value="User ID"/>
<h:inputText id="username" value="#{credentials.username}"
required="true" size="20" />
</div>
<div class="form-row">
<h:outputLabel for="password" value="Password"/>
<h:inputSecret id="password" type="password" value="#
{credentials.password}" required="true" />
</div>
<div class="form-row">
<h:commandButton styleClass="btn btn-warning" value="Sign In"
type="submit" action="#{login.login}" />
<a href="#" id="forgot-password">Forgot you password?</a>
</div>
</fieldset>
</h:form>
Вот мой Логин боб (код был раздели и редактируются только продемонстрировать соответствующие части):
import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.Produces;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.security.auth.Subject;
import javax.security.auth.login.CredentialExpiredException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
@SessionScoped
@Named
public class Login implements Serializable {
private static final long serialVersionUID = 7965455427888195913L;
@Inject
private Credentials credentials;
@PersistenceContext
private EntityManager userDatabase;
@Inject
LoginService loginService;
private Users currentUser;
private Service service;
private String uniqueSecurityName;
private String l;
@SuppressWarnings("unchecked")
public String login() {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
System.out.println("The login method has been called.");
try {
Principal userPrincipal = request.getUserPrincipal();
request.getUserPrincipal();
if (userPrincipal != null) {
request.logout();
}
request.login(credentials.getUsername(), credentials.getPassword());
String name = userPrincipal.getName();
System.out.println("getRemoteUser?.." + request.getRemoteUser());
System.out.println("getUserPrincipal?.." + request.getUserPrincipal());
System.out.println("getAuthType?.." + request.getAuthType());
Donor donor = loginService.getDonor(credentials.getUsername());
currentUser = new Users();
currentUser.setLocation(donor.getCenter().getCity());
currentUser.setRole("DONOR");
currentUser.setUserId(credentials.getUsername());
currentUser.setFirstName(donor.getFirstName());
currentUser.setLastName(donor.getLastName());
currentUser.setUsername(credentials.getUsername());
currentUser.setName(credentials.getUsername());
return "users?faces-redirect=true";
} catch (Exception e) {}
return null;
}
public void logout() {
currentUser = null;
}
public boolean isLoggedIn() {
return currentUser != null;
}
@Produces
@LoggedIn
public Users getCurrentUser() {
return currentUser;
}
}
Вот мой Credentials боб :
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Default;
import javax.inject.Named;
@RequestScoped
@Named
@Default
public class Credentials implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6976596855571123825L;
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Адрес следующей страницы users.xhtml (для проверки на проверку s ession информация):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Login</title>
<link href="style/main.css" rel="stylesheet" type="text/css"/>
<ui:insert name="head"/>
</head>
<body>
<div id="container">
<div id="header">
</div>
<div id="sidebar">
</div>
<div id="content">
<h1>Current User</h1>
<h:dataTable value="#{login.currentUser}" var="u">
<h:column>
<f:facet name="header">
Username
</f:facet>
<h:outputText value="#{u.username}" />
</h:column>
<h:column>
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{u.name}" />
</h:column>
<h:column>
<f:facet name="header">
Password
</f:facet>
<h:outputText value="#{u.password}" />
</h:column>
</h:dataTable>
</div>
<br style="clear:both"/>
</div>
</body>
</html>
Вот мой Пользователи боб:
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;
@Entity
public class Users {
@Id
private String username;
private String name;
private String password;
@Transient
private String role;
@Transient
private String location;
@Transient
private String userId;
@Transient
private String firstName;
@Transient
private String lastName;
public Users() {
}
public String getUsername() {
return username;
}
public void setName(String name) {
this.name = name;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return "User (username = " + username + ", name = " + name + ")";
}
}
Зв Многое. Текст. – kolossus
Вход должен быть '@ RequestScoped', и вы должны иметь управляемый bean-элемент' @ SessionScoped' для обработки пользовательских данных или даже обрабатывать его как атрибут сеанса. –
@kolossus Ну, Java Security, IMO, возможно, является самой сложной Java EE, которая может охватить рассмотрение j_security_check vs Programmatic Security и настройку домена/области для вашего конкретного контейнера. Проблема в том, что если я не буду точно описывать свою проблему, кто-то собирается тратить свое время и свое время на предоставление ответа, который бесполезен для решения моей проблемы. –