Solucionado (ver solução)
Solucionado
(ver solução)
12
respostas

RENDERED não deixa acessar as páginas.

Boa noite, tenho um pequeno problema no sistema, o meu loguin está certo correto, não deixa acessar as paginas do meu sistema sem estar logado, quando tento, volta para a pagina do loguin, no meu sistema eu fiz a modelagem da seguinte maneira.

@Entity
@SuppressWarnings("serial")
public class Usuario implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long codigo;
    private String login;
    private String senha;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "nivel_codigo")
    private NivelDeAcesso nivelDeAcesso = new NivelDeAcesso();
    private String confirmaSenha;
    @Lob
    private byte[] foto;
@Entity
@SuppressWarnings("serial")
public class NivelDeAcesso implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long codigo;
    @Enumerated(EnumType.STRING)
    private NivelAcesso nivelAcesso;
    @OneToOne(mappedBy = "nivelDeAcesso")
    private Usuario usuario;
public enum NivelAcesso {
    ACESSONORMAL, ACESSOLIMITADO, ACESSOSUPERIOR;
}

Depois tenho meus xhtml, quando uso o componente rendered, ele atende muito bem oque quero fazer, como por exemplo, acessar a pagina quem tiver o acessonomal ou o acessosuperior.

rendered="#{usuarioBean.usuario.nivelDeAcesso.nivelAcesso == 'ACESSOSUPERIOR' || usuarioBean.usuario.nivelDeAcesso.nivelAcesso == 'ACESSONORMAL'}"

Aqui estou renderizando uma pagina de cadastro, mais quando entro com o acessolimitado, essa página não fica a mostra na minha tela, mais quando acesso a pagina na url, quando escrevo na url aceita entrar, como fazer isso não acontecer?

12 respostas

Bom dia Alisson, Entendo que você deveria realizar um controle de acesso as páginas através de Filter (JEE). O rendered do JSF é apenas para controle de renderização das informações na página em si, mas o controle de acesso a página deve ser de outro modo, ou seja, antes da renderização. Veja se ajuda algo do tipo:

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

Thiago não entendi muito esses codigos ai. Esse é para controle de paginas né? mais não vi em lugar nenhum falando quem pode acessar minhas paginas.

Isso! O Filter pode ser utilizado de várias formas, dentre elas, controlar o acesso a determinados conteúdos do seu aplicativo. Vou tentar resumir o exemplo de código: -Existe um annotation no Filter @WebFilter informando que o Filter irá ser requisitado para todas as páginas contida no endereço "/integra/user/*" -Dentro de doFilter() é recuperado da sessão o objeto Authorization e verificado se pode acessar o endereço. Caso positivo permite prosseguir a cadeia de Filter até chamar a página requisitada. Caso negativo, redireciona para a página de login.

Minha sugestão: você criar um Filter igual ao exemplo e dentro do método doFilter() obter o objeto usuarioBean e verificar no atributo nivelAcesso o valor. Caso atenda a regra de que a página pode ser exibida para esse determinado usuário, permite prosseguir a cadeia de Filter até chamar a página requisitada. Caso negativo, redireciona para a página de login.

Abraços,

Hum comecei a entender o sentido, só fiquei perdido como irei fazer a verificação, quando você me falo.

"Minha sugestão: você criar um Filter igual ao exemplo e dentro do método doFilter() obter o objeto usuarioBean e verificar no atributo nivelAcesso o valor. Caso atenda a regra de que a página pode ser exibida para esse determinado usuário, permite prosseguir a cadeia de Filter até chamar a página requisitada. Caso negativo, redireciona para a página de login."

Aonde eu faço esse verificação? Desde já obrigado

A verificação você faz na classe de Filter. Ao realizar a primeira requisição na aplicação você faz o usuário se logar, correto? Após se logar, muito provavelmente você está armazenando o objeto UsuarioBean (Managed Bean) ou o objeto Usuario (utilizado dentro do Managed Bean) em escopo de sessão. Algo como:

//Armazena na sessão objeto usuarioBean
req.getSession().setAttribute("usuarioBean", usuarioBean)

//Armazena na sessão objeto usuario
req.getSession().setAttribute("usuario", usuario)

//Obtém na sessão objeto usuarioBean
req.getSession().getAttribute("usuarioBean")

//Obtém na sessão objeto usuario
req.getSession().getAttribute("usuario")

Na sua classe de Filter, ficaria algo do tipo:

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest req = (HttpServletRequest) request;

UsuarioBean usuarioBean = (UsuarioBean) req.getSession().getAttribute("usuarioBean")

/* Simples verificação, mas você pode criar um método específico que retorne um valor booleano */
if(usuarioBean != null && usuarioBean.usuario.nivelDeAcesso.nivelAcesso != 'ACESSOSUPERIOR'){
    //deixa continuar a requisição
    chain.doFilter(request, response);
}

//ou

Usuario usuario = (Usuario) req.getSession().getAttribute("usuario")

/* Simples verificação, mas você pode criar um método específico que retorne um valor booleano */
if(usuario != null && usuario.nivelDeAcesso.nivelAcesso != 'ACESSOSUPERIOR'){
    //deixa continuar a requisição
    chain.doFilter(request, response);
}

Abraços

Depois, veja se faz o curso 'Curso Servlets: Fundamentos de Java na Web' para entender o que estou explanando. O JSF e todos os frameworks web de mercado agem acima de Servlets e recursos Java EE.

Thiago muitissimo obrigado, e desculpa a falta de conhecimento, por exemplo meu sistama tem 20 paginas, eu quero que apenas 3 ficam acesso restrito, para apenas acessosuperior acessar elas, como fazer nessas 3 paginas isso, porque pelo oque eu vi, no metodo que você passou acima ele restringe todas paginas, ou estou errado?

Fica tranquilo quanto a conhecimento! Mesmo estudando a vida toda, nós iremos morrer não sabendo tudo!

Quanto a restringir no Filter, você pode restringir as páginas usando o atributo coringa * (todo o conteúdo da pasta) ou declarar apenas as páginas específicas que devem passar pelo Filter.

Segue exemplo utilizando coringa:

@WebFilter(filterName = "TimeOfDayFilter",
urlPatterns = {"/integra/user/*"},
initParams = {
    @WebInitParam(name = "mood", value = "awake")})
public class TimeOfDayFilter implements Filter {

Segue exemplo utilizando apenas as páginas específicas

@WebFilter(filterName = "TimeOfDayFilter",
urlPatterns = {"/integra/user/a.xhtml", "/integra/user/b.xhtml", "/integra/user/c.xhtml"},
initParams = {
    @WebInitParam(name = "mood", value = "awake")})
public class TimeOfDayFilter implements Filter {

Para mais informações e detalhes da especificação do WebFilter, documentação Oracle:

Classe WebFilter: http://docs.oracle.com/javaee/6/api/javax/servlet/annotation/WebFilter.html#urlPatterns()

The Java EE 6 Tutorial: http://docs.oracle.com/javaee/6/tutorial/doc/bnagb.html

solução!

Fala Alisson, blz? É bem o que o Thiago disse, o rendered não deveria ter essa função de controlar o acesso do Usuário.

Usar Filtro é uma opção válida e funciona! Mas da uma pesquisada na API de segurança do JavaEE o JAAS, ela é feita justamente para autorização e autenticação.

Abraço

Fala Samir tudo bom? Sim sim o thiago tá me ajudando bastante aqui kkkkk, e oque você disse me interessou muito kkk. Como o controle de login de segurança estou usando o Phaslistener que atente muito bem a parte do login.

public class Autorizador implements Serializable, PhaseListener {

    private static final long serialVersionUID = 1L;

    @Override
    public void afterPhase(PhaseEvent event) {
        FacesContext context = event.getFacesContext();
        String pagina = context.getViewRoot().getViewId();
        System.out.println("Nome da paginas: " + pagina);
        if ("/paginas/usuario.xhtml".equals(pagina)) {
            System.out.println("Igual");
            return;
        } else {

        }
        Usuario usuarioLogado = (Usuario) context.getExternalContext()
                .getSessionMap().get("usuarioLogado");
        if (usuarioLogado != null) {
            return;
        }
        NavigationHandler handler = context.getApplication()
                .getNavigationHandler();
        handler.handleNavigation(context, null,
                "/paginas/usuario?faces-redirect=true");

        context.renderResponse();
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        // TODO Auto-generated method stub

    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

}

Aqui controla se o usuario tentar logar no meu sistema sem ele ter feito o login ele me retornara a pagina de login mesmo. A parte do login eu estou satisfeito dessa forma, não queria implementar outra regra, só queria a controle de paginas mesmo, essa JAAS, faz isso para mim? Posso implementar essa biblioteca apenas para controle de acesso a paginas? Porque quero continuar usando o PlaseListener para o login.

Então Alisson, como a gnt já conversou anteriormente, não tem muito certo e errado (minha opnião pessoal), tem o que funciona pra sua aplicação. O phaseListener é uma forma do JSF verificar onde está no seu ciclo de vida, pode ser feita a autorização por ai, assim como pode ser feita com Filtros como o Thiago mostrou. Com o JaaS é mais seguro, já que é uma API para isso. Esse é o link do curso da alura que tem JaaS: https://cursos.alura.com.br/course/java-ee-webapp-3

ele é continuação de outros dois cursos de JavaEE.

Existem outras ferramentas de segurança também, como por exemplo o Spring Security, mas vale a pena dar uma olhada no curso e tentar colocar na sua aplicação.

kkk verdade não existe o certo e o errado, tá bem irei dar uma olhada, aqui aprenderei como fazer a restrição que quero fazer? De controlar paginas? obg