UserDetailsService

O método do UserDetailsService é tentar encontrar um usuário por Username. Como nosso Username na verdade é o email, precisamos:

  1. Criar um UserRepository com o método "findByEmail". Como já sabemos, o Repository consegue realizar a busca em virtude do "by". Para que ele consiga também buscar as roles desse usuário, faremos uma consulta SQL raíz.

Nesse ponto, nós já sabemos!

  • Criar uma UserDetailsProjection no pacote projections, com os atributos em get:

public interface UserDetailsProjection {

	String getUsername();
	String getPassword();
	Long getRoleId();
	String getAuthority();
}
  • Fazer a consulta no UserRepository, usando o projection com o SQL

Query(nativeQuery = true, value = """
			SELECT tb_user.email AS username, tb_user.password, tb_role.id AS roleId, tb_role.authority
			FROM tb_user
			INNER JOIN tb_user_role ON tb_user.id = tb_user_role.user_id
			INNER JOIN tb_role ON tb_role.id = tb_user_role.role_id
			WHERE tb_user.email = :email
		""")
List<UserDetailsProjection> searchUserAndRolesByEmail(String email);
  1. Injetar esse Repository no UserService, e utilizá-lo dentro do método advindo da interface (UserDetailsService):

  1. Criaremos uma lista do tipo projection e usamos o método do repository passando o username;

  2. Se ela estiver vazia, lançamos a exceção;

  3. Caso contrário, instanciaremos um User, setaremos o seu email e password;

  4. Para settar as roles, faremos um for:

    • Para cada Projection dentro da lista result, entraremos no objeto User e utilizaremos o método addRole;

    • Dentro dele, criaremos um new Role, passando o roleId e tipo de authority :)

  5. Retorna o user depois.

Atualizado