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

Erro ao acessar localhost:8080/casadocodigo/produtos/

Pessoal tudo bem ?

Estou com problema ao acessar o link Erro ao acessar localhost:8080/casadocodigo/produtos/, quanto tento acessar esta uri sem estar logado a aplicacao quebra. Caso eu acesse sem o /produtos no final, o projeto funciona normalmente.

Segue o pastebin para analise (stacktrace)

https://pastebin.com/zaBmgnf2

meu usuario, modifiquei o nome para username, senha para password.

Spring Securiti

package br.com.casadocodigo.loja.conf;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import br.com.casadocodigo.loja.dao.UsuarioDAO;

// classe responsavel por receber as configuracoes do spring
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired(required = true)
    private UsuarioDAO usarioDAO;

    // ira configura as configuracoes e permissoes.
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/produtos/form").hasRole("ADMIN")
            .antMatchers("/carrinho/**").permitAll()
            .antMatchers("/pagamento/**").permitAll()
            .antMatchers(HttpMethod.POST, "/produtos").hasRole("ADMIN")
            .antMatchers(HttpMethod.GET, "/produtos/**").hasRole("ADMIN")
            .antMatchers("/resources/**").permitAll()
            .antMatchers("/").permitAll()
            .anyRequest().authenticated()
            .and().formLogin().loginPage("/login").permitAll()
            .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
    }

    // metodo que cuida dos detalhes dos usuarios
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(usarioDAO).passwordEncoder(new BCryptPasswordEncoder());

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**");
    }

}

Usuario.

package br.com.casadocodigo.loja.models;

@Entity
public class Usuario implements UserDetails {

    /**
     * 
     */
    private static final long serialVersionUID = -6515237668914804962L;
    @Id
    private String email;
    private String password;
    private String username;

    @OneToMany(fetch = FetchType.EAGER)
    private List<Role> roles = new ArrayList<Role>();

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.roles;
    }
    // solitando a senha
    @Override
    public String getPassword() {
        return this.password;
    }


    // solitando o usuario
    @Override
    public String getUsername() {
        return this.email;
    }


    // conta nao expirada
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }


    // conta nao bloqueada
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }


    // credencial nao esta expirada?
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    // esta habilitado 
    @Override
    public boolean isEnabled() {
        return true;
    }

    public String getNome() {
        return username;
    }

    public void setNome(String nome) {
        this.username = nome;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getSenha() {
        return password;
    }

    public void setSenha(String senha) {
        this.password = senha;
    }


    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }



}

Link do git: https://bitbucket.org/Sleepk/spring-2

4 respostas

Oi Julio, você pode postar aqui a stacktrace pra gente poder identificar o que pode estar gerando o erro?

Thais, tudo bem ?

A stacktrace, esta dentro pastebin disponibilizado la em cima, mas segue novamente o link:

https://pastebin.com/zaBmgnf2
solução!

Desculpe, acabei abrindo o bitbucket e não reparei que já tinha enviado.

O erro:

Invalid property 'principal.username' of bean class [org.springframework.security.authentication.
AnonymousAuthenticationToken]: Bean property 'principal.username' is not readable or has an invalid getter method: 
Does the return type of the getter match the parameter type of the setter?

Acusa que a propriedade principal.username possui um método getter inválido. Veja que na sua classe Usuario você trocou o nome do usuario por username e manteve os getters and setters como getNome e setNome. Mas como você implementou a interface UserDetails, ela te obriga a ter um getUsername, mas no seu código esse cara é o email, e não o atributo username da classe Usuario. Troque para a maneira que o professor usou, caso contrário, você não conseguirá buscar o nome do usuário:

@Id
private String email;
private String nome;
private String senha;

Troque o nome do seu atributo username para nome e arrume os métodos getNome e setNome. Meu chute é que o Spring tenha se perdido aí apesar de existir um getUsername na sua classe. veja se funciona.

Outra coisa é que "/produtos" é acessível apenas pelo administrador conforme sua configuração:

.antMatchers("/produtos/form").hasRole("ADMIN")
.antMatchers(HttpMethod.POST, "/produtos").hasRole("ADMIN")
.antMatchers(HttpMethod.GET, "/produtos/**").hasRole("ADMIN")

portanto, apenas o administrador vai ter acesso a "/produtos/**"

Thais, tudo bem ?

Consegui fazer o projeto funcionar conforme eu queria .../produtos/, o que encontrei que estava dando erro era a questao de:

<security:authentication  property="principal" var="usuario"/>

da lista.jsp, por algum motivo eu estava lendo principal.username e a aplicacao estava quebrando.

Corrigi tambem as questoes relacionados aos nomes em ingles que havia colocado, tambem refiz os getter e setter :D

Tambem foi colocado a questao exibicao da listagem de produtos quando autenticado no cabeçalho.

<security:authorize access="isAuthenticated()">

Modificado tambem as permissoes no securityConfiguration conforme indicado logo acima.

Agradeço ao suporte, desculpa a bagunça hahaha. Esta sendo quase todo teste ou build da aplicacao um 7 a 1 diferente hahaha.