tutorial showcase mvc etiquetas español ejemplo concepto bean jsf jsf-2 servlet-filters login-control

showcase - JSF: ¿Cómo controlar el acceso y los derechos en JSF?



primefaces showcase (1)

Bueno, este es un tema bastante amplio. Cuando empiece con la autenticación de fabricación casera, buscaré la respuesta en la autorización de elaboración propia.

La comprobación de roles en Java / JSF es relativamente simple si el modelo está sensiblemente diseñado. Suponiendo que un solo usuario puede tener múltiples roles (como suele ser el caso en aplicaciones del mundo real), en última instancia, le gustaría terminar teniendo algo como:

public class User { private List<Role> roles; // ... public boolean hasRole(Role role) { return roles.contains(role); } }

public enum Role { EMPLOYEE, MANAGER, ADMIN; }

para que pueda comprobarlo de la siguiente manera en sus vistas 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'')}" />

y en tu filtro:

String path = req.getRequestURI().substring(req.getContextPath().length()); if (path.startsWith("/integra/user/admin/") && !user.hasRole(Role.ADMIN)) { res.sendError(HttpServletResponse.SC_UNAUTHORIZED); }

La parte más difícil es traducir este modelo de Java a un modelo de DB sano. Hay varias formas diferentes en función de los requisitos comerciales concretos, cada uno con sus propias (des) ventajas. ¿O quizás ya tiene un modelo de base de datos en el que tiene que basar su modelo de Java (por lo tanto, necesita diseñar de abajo hacia arriba)?

De todos modos, suponiendo que esté utilizando JPA 2.0 (su historial de preguntas al menos lo confirma) y que puede diseñar de arriba hacia abajo, una de las maneras más fáciles sería asignar la propiedad de roles como una @ElementCollection contra una tabla de user_roles . Como estamos usando una enumeración de Role , no es necesaria una segunda tabla de role . Una vez más, eso depende de los requisitos funcionales y empresariales concretos.

En términos genéricos de SQL, la tabla user_roles puede verse así:

CREATE TABLE user_roles ( user_id BIGINT REFERENCES user(id), role VARCHAR(16) NOT NULL, PRIMARY KEY(user_id, role) )

Que luego se asigna de la siguiente manera:

@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;

Eso es básicamente todo lo que necesitas cambiar en tu entidad de User .

Junto a la autenticación de fabricación propia (inicio / cierre de sesión) y la autorización (verificación de roles), también hay una autenticación administrada por contenedor provista por Java EE con la que puede iniciar sesión con j_security_check o HttpServletRequest#login() , filtrar las solicitudes HTTP por <security-constraint> en la web.xml , verifique el usuario que web.xml sesión con #{request.remoteUser} y sus roles con #{request.isUserInRole(''ADMIN'')} , etc.

Luego hay varios marcos de terceros, como picketlink.org , Spring Security , Apache Shiro , etc. Pero todo esto está fuera de discusión :)

Me gustaría controlar el acceso después de que el usuario inicie sesión en mi sistema.

Por ejemplo:

administrator : can add, delete and give rights to employee employee : fill forms only ...

Entonces, después de saber qué derecho tiene el usuario, al registrar la base de datos, me gustaría restringir lo que este usuario puede ver y hacer. ¿Hay una manera simple de hacer eso?

EDITAR

@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() { } }