JSF: Как контролировать доступ и права в JSF?
Я хотел бы контролировать доступ после входа пользователя в мою систему.
Например:
administrator : can add, delete and give rights to employee
employee : fill forms only
...
Поэтому, узнав, какое право имеет пользователь, проверяя базу данных, я хотел бы ограничить то, что этот пользователь может видеть и делать. Есть простой способ сделать это?
РЕДАКТИРОВАТЬ
@WebFilter("/integra/user/*")
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) request;
Authorization authorization = (Authorization) req.getSession().getAttribute("authorization");
if (authorization != null && authorization.isLoggedIn()) {
// User is logged in, so just continue request.
chain.doFilter(request, response);
} else {
// User is not logged in, so redirect to index.
HttpServletResponse res = (HttpServletResponse) response;
res.sendRedirect(req.getContextPath() + "/integra/login.xhtml");
}
}
// You need to override init() and destroy() as well, but they can be kept empty.
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
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
enum, секунда 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
юридическое лицо.
Помимо домашней аутентификации (вход в систему / выход из системы) и авторизации (проверка роли), есть также Java EE, обеспечивающая управляемую контейнером аутентификацию, с которой вы можете войти через j_security_check
или же HttpServletRequest#login()
, фильтровать HTTP-запросы по <security-constraint>
в web.xml
проверьте зарегистрированного пользователя #{request.remoteUser}
и его роль по #{request.isUserInRole('ADMIN')}
, так далее.
Тогда есть несколько сторонних фреймворков, таких как PicketLink, Spring Security, Apache Shiro и т. Д. Но об этом вообще не может быть и речи:)