Authentication with Spring Boot, Security, Using Bank Html Page, User and Password

Asked

Viewed 3,841 times

0

Hello,

I am starting with Spring Boot and am caught in a problem with the spring security configuration. I’m trying to do the login part of the page, I made the settings with what I found material on the internet but it’s not working. The problem is this, when opening the default login page of spring security I try to log in with the registered user in the bank but he says it does not exist, I can only log in with the default user of spring, "user" and the automatically generated password: "Using generated security password: b8728e...". How do I disable this default user to search by user in my database?

I also tried to use user in memory but tb did not give.

Configuration classes:

@Configuration
@EnableWebSecurity
public class SecurityWebConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ImplementsUserDetailsService userDetailsService;

     @Override
     protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable().authorizeRequests().antMatchers(HttpMethod.GET, "/" ).permitAll()
            .anyRequest().authenticated()
            .and().formLogin().permitAll()      
            .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"));

          }

      @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("lucas").password("123").roles("ADMIN");

        //userDetailsService(userDetailsService)
        //.passwordEncoder(new BCryptPasswordEncoder());

    }

    @Override  
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/css/**", "/imagem/**", "/js/**");
    }
}
@Repository
public class ImplementsUserDetailsService implements UserDetailsService {

    @Autowired
    private UsuarioRepository ur;

    @Override
    public UserDetails loadUserByUsername(String nomeusuario) throws UsernameNotFoundException {

        Usuario usuario = ur.findByNomeusuario(nomeusuario);

        if(usuario == null)
            throw new UsernameNotFoundException("Usuario não encontrado!"); 

        return usuario;
    }

}
@Repository
public interface UsuarioRepository extends JpaRepository<Usuario, Long> {

    Usuario findByNomeusuario(String nomeusuario);

}
@Controller
public class IndexController {

    @GetMapping("/")
    public String index() {

        return "index";
    }

    @GetMapping("/login")
    public String login() {

        return "login";
    }
}
@Entity
public class Usuario implements Serializable, UserDetails{

private static final long serialVersionUID = 1L;


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long idUsuario;

    private String nomeusuario;


    private String senha;


    private float salario;


    public long getIdUsuario() {
        return idUsuario;
    }


    public void setIdUsuario(long idUsuario) {
        this.idUsuario = idUsuario;
    }



    public String getNomeusuario() {
        return nomeusuario;
    }


    public void setNomeUsuario(String nomeusuario) {
        this.nomeusuario = nomeusuario;
    }


    public String getSenha() {
        return senha;
    }


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


    public float getSalario() {
        return salario;
    }


    public void setSalario(float salario) {
        this.salario = salario;
    }


    public static long getSerialversionuid() {
        return serialVersionUID;
    }


    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }


    @Override
    public String getPassword() {
        return this.senha;
    }


    @Override
    public String getUsername() {
        return this.nomeusuario;
    }


    @Override
    public boolean isAccountNonExpired() {
        return true;
    }


    @Override
    public boolean isAccountNonLocked() {
        return true;
    }


    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }


    @Override
    public boolean isEnabled() {

        return true;
    }
}

inserir a descrição da imagem aqui

  • you will not be able to even, because, the authentication is not searching from the database, review your file Securitywebconfig in the configure method, you are using: auth.inMemoryAuthentication(), and should use: userDetailsService in which it is commented

  • the findByNomeuser method is strange, check if it is really working and how is the nomenclature in the Entity, would not be, findByNomeUsuario?

  • This with auth.inMemoryAuthentication() because it was testing, but with what this commented also did not work. About findByNomeUsuario, I did the same as this in the User model as this user name

  • change findByNomeuser to findByNomeUsuario

  • in the database the password must be encrypted, because you are using Bcryptpasswordencoder in Spring

  • findByNomeUsuario so of the error. I will change in the bank and the model to see if this is it

  • Yes, the bank is encrypted

  • post in question your Entity and how is in the bank

  • I posted on the question

  • This example is complete, in your absence the Customauthenticationmanager, however, it uses JWT: https://answall.com/questions/149735/authenticates%C3%A7%C3%a3o-com-spring-security? Rq=1

  • In my ImplementsUserDetailsService, i have these settings: @Resource(name = "userService") private Userdetailsservice userDetailsService; @Autowired public void globalUserDetails(Authenticationmanagerbuilder auth) throws Exception { auth.userDetailsService(userDetailsService). passwordEncoder(Encoder()); }

  • your ImplementsUserDetailsService is wrong, you need to write it down with @Service(value = "usuarioService") instead of @Repository

  • I altered it to identify the parameters by the hairs I created: .formLogin().usernameParameter("nomeUsuario").passwordParameter("senha").loginPage("/login") .permitAll() but did not give tb, I will try to make these other changes you sent

  • What is the version of your spring? spring mvc 4? mvc 3? is spring boot?

  • Spring boot 2.1.6

  • updated my answer, I am using Spring Boot 2.0.1

Show 11 more comments

1 answer

1

I did an implementation of Spring Boot with Security simple only for this, with access to User and Password via Html, database Postgres however, it can be any other sql.

With a table: user
With the fields: id, username, password

If you want you can create the table in postgres with the command:

CREATE TABLE user(
   id serial PRIMARY KEY,
   username VARCHAR (50) UNIQUE NOT NULL,
   password VARCHAR (250) NOT NULL
);

But you can also let Hibernate generate for you by configuring the file: application.properties with the following instruction:

spring.jpa.hibernate.ddl-auto=create

If you really want to create the table at hand, then change this statement to validate:

spring.jpa.hibernate.ddl-auto=validate

Implementation for Userdetailsservice:

package hello;

import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

@Service(value = "usuarioService")
public class MyUserDetailService implements UserDetailsService {

    @Autowired
    private UsuarioRepo usuarioRepo;    

    @Autowired
    private BCryptPasswordEncoder bcryptEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) {
        Optional<User> opt = usuarioRepo.findByUsername(username);
        User user = null;
        if(opt.isPresent()){
            user = opt.get();
        }
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        return new MyUserPrincipal(user);
    }

    public User save(User usuario) {
        usuario.setPassword(bcryptEncoder.encode(usuario.getPassword()));
        return usuarioRepo.save(usuario);
    }
}

Implementation of Userdetails:

package hello;

import java.util.Collection;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import lombok.Getter;
import lombok.Setter;

@Getter @Setter
public class MyUserPrincipal implements UserDetails {

    private static final long serialVersionUID = -8489053074208206273L;

    private User user;

    public MyUserPrincipal(User user) {
        this.user = user;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

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

User Entity:

package hello;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter @Setter @AllArgsConstructor @NoArgsConstructor
@Entity
public class User {

    //FIXME: #### está funcionando, mas o ideal é depois avaliar o uso de Sequence, Identity, Serial...

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false, unique = true)
    private String username;

    private String password;


}

Repository:

package hello;

import java.util.Optional;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UsuarioRepo extends CrudRepository<User, String> {

    Optional<User> findByUsername(String username);

}

Implementation of Websecurityconfigureradapter:

package hello;

import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    //FIXME: #### após os testes, remover o mapeamento new-user tanto da controller como das permissoes abaixo ####
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home", "/new-user").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder());
    }

    @Bean
    public BCryptPasswordEncoder encoder(){
        return new BCryptPasswordEncoder();
    }

    @Resource(name = "usuarioService")
    private UserDetailsService userDetailsService;

}

Controller:

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

    //FIXME: #### quando tudo já estiver ok, e o usuário já criado, remover o mapeamento new-user ####

@Controller
public class UsuarioController {

    @Autowired
    MyUserDetailService usuarioService;

    @GetMapping("/")
    public String root() {
        return "login";
    }

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/home")
    public String home() {
        return "home";
    }

    @GetMapping("/new-user")
    public String newUser() {
        User usuario = new User();
        usuario.setId(1L);
        usuario.setUsername("danilo");
        usuario.setPassword("123");
        usuarioService.save(usuario);
        return usuario.toString();
    }

}

Pom.xml using postgres, jpa, Thymeleaf, and Lombok

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-securing-web</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application properties:

Configure the database, user and password

spring.datasource.hikari.connectionTimeout=100000
spring.datasource.hikari.maximumPoolSize=50
#escolha um banco de dados, nesse caso esta: dbteste 
spring.datasource.url=jdbc:postgresql://localhost:5432/dbteste
spring.datasource.username=userteste
spring.datasource.password=senha
#create ira criar a tabela
#create-drop ao encerrar a aplicacao ele dropa as tabelas
#validate ele verifica se as tabelas estao conforme as entidades
spring.jpa.hibernate.ddl-auto=create #validate #create-drop

hello.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
        <form th:action="@{/logout}" method="post">
            <input type="submit" value="Sign Out"/>
        </form>
    </body>
</html>

login.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example </title>
    </head>
    <body>
        <div th:if="${param.error}">
            Invalid username and password.
        </div>
        <div th:if="${param.logout}">
            You have been logged out.
        </div>
        <form th:action="@{/login}" method="post">
            <div><label> User Name : <input type="text" name="username"/> </label></div>
            <div><label> Password: <input type="password" name="password"/> </label></div>
            <div><input type="submit" value="Sign In"/></div>
        </form>
    </body>
</html>

home html.:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example</title>
    </head>
    <body>
        <h1>Welcome!</h1>

        <p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
    </body>
</html>

pages were created (home html.,hello.html,login.html) using the Thymeleaf+spring boot convention:

inserir a descrição da imagem aqui

Execute the command:

On linux:
mvn clean install; java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 -jar target/Gs-Securing-web-0.1.0.jar

On Windows:
mvn clean install & java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 -jar target/Gs-Securing-web-0.1.0.jar

Sign in:

http://localhost:8080/new-user  

An error page will appear, as it will try to upload to a Thymeleaf template that does not exist, however, with the user created in the description:

inserir a descrição da imagem aqui

Log in now to the page:

http://localhost:8080/hello

You will not be logged in and will be redirected, log in, and password: Anilo, 123

inserir a descrição da imagem aqui

After logging in, you will be automatically redirected to the hello page:

inserir a descrição da imagem aqui

  • I made these changes but came to nothing. Ta difficult kkkk. I believe that what is causing this problem is the issue of spring security generating a password to log in

  • I added the save method, use it to create a user.

  • I found a booklet from Caelum here, I’ll try to make this part from scratch and see what happens. If it works here. Thank you so much for your help and attention :)

  • I made an implementation using page user+password just for this and it worked perfectly

  • @Lucascarravetta, and I put in the answer, with all the structure.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.