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?

Garanta sua matrícula hoje e ganhe + 2 meses grátis

Continue sua jornada tech com ainda mais tempo para aprender e evoluir

Quero aproveitar agora
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