Ответ 1
Хорошо, это довольно широкий предмет. Когда вы начнете с проверки подлинности на дому, я настрою таргетинг на ответ на авторизацию на дому.
Проверка роли в Java/JSF является относительно простой, если модель разумно разработана. Предполагая, что один пользователь может иметь несколько ролей (как это часто бывает в приложениях реального мира), вы в конечном итоге хотели бы иметь что-то вроде:
public class User {
private List<Role> roles;
// ...
public boolean hasRole(Role role) {
return roles.contains(role);
}
}
public enum Role {
EMPLOYEE, MANAGER, ADMIN;
}
чтобы вы могли проверить его в своих представлениях JSF следующим образом:
<h:selectManyCheckbox value="#{user.roles}" disabled="#{not user.hasRole('ADMIN')}">
<f:selectItems value="#{Role}" />
</h:selectManyCheckbox>
<h:commandButton value="Delete" rendered="#{user.hasRole('ADMIN')}" />
и в вашем фильтре:
String path = req.getRequestURI().substring(req.getContextPath().length());
if (path.startsWith("/integra/user/admin/") && !user.hasRole(Role.ADMIN)) {
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
Самая сложная часть - перевод этой Java-модели на разумную модель БД. Существует несколько разных способов, в зависимости от конкретных бизнес-требований, каждый из которых имеет свои преимущества. Или, возможно, у вас уже есть модель БД, на которой вы должны основывать свою модель Java (таким образом, вам нужно создать снизу вверх)?
В любом случае, предполагая, что вы используете JPA 2.0 (ваша история вопроса хотя бы подтверждает это), и что вы можете проектировать сверху вниз, одним из самых простых способов было бы сопоставить свойство roles
как @ElementCollection
в таблице user_roles
. Поскольку мы используем перечисление Role
, вторая таблица Role
не нужна. Опять же, это зависит от конкретных функциональных и бизнес-требований.
В общих терминах SQL таблица user_roles
может выглядеть так:
CREATE TABLE user_roles (
user_id BIGINT REFERENCES user(id),
role VARCHAR(16) NOT NULL,
PRIMARY KEY(user_id, role)
)
который затем должен отображаться следующим образом:
@ElementCollection(targetClass=Role.class, fetch=FetchType.EAGER)
@Enumerated(EnumType.STRING)
@CollectionTable(name="user_roles", joinColumns={@JoinColumn(name="user_id")})
@Column(name="role")
private List<Role> roles;
Это в основном все, что вам нужно изменить в вашей организации User
.
Рядом с проверкой подлинности на дому (login/logout) и авторизацией (проверка роли) существует также Java EE, предоставляемая управляемая контейнером аутентификация, с которой вы может войти по j_security_check
или HttpServletRequest#login()
, фильтровать HTTP-запросы <security-constraint>
в web.xml
, проверить зарегистрированного пользователя #{request.remoteUser}
и его роли #{request.isUserInRole('ADMIN')}
и т.д.
Тогда есть несколько сторонних фреймворков, таких как PicketLink, Spring Безопасность, Apache Shiro и т.д. Но об этом не может быть и речи:)