Spring Security. Managing users
Tags: webdev, security, database, tristan
Published: 2022-02-28 03:39:39

###Introduction
- This series is going to be on Spring Security. This tutorial assumes that you already have your spring project set up, if you do not, please check out the YouTube video [HERE](https://www.youtube.com/watch?v=9SGDpanrc8U&t=1482s) 

###GitHub
[HERE](https://github.com/thePlebDev/Spring-security-examples/tree/master/src/main/java/com/example/demo)

###YouTube version
[HERE](https://youtu.be/bWtpZ34J55c)

###Managing Users
- So we know that we implement the `UserDetails` interface to describe users such that Spring Security understands them. But how does Spring Security manage them? Well that is done with the `UserDetailsService` interface.

###UserDetailsService
- This interface only contains one method, which is `loadUserByUsername()`. This method is called by Spring Security whenever any time an object needs to be authenticated. This method takes in a String called `username`(considered to be unique). The object that is returned by this method is an instance of the `UserDetails` interface and if the user is not found, then the method throws a UsernameNotFoundException exception.
- So now we can create a new class, call it `CustomUserDetailsService` and have it implement the `UserDetailsService`.

```
public class CustomUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return null;
    }
}

```
- Since we are making our own UserDetailsService, it has to search for a user and that means talking to our database. Talking to a database is done through a Repository.

### Repository 
- The whole goal of a repository in Spring is to significantly reduce the amount of boilerplate code required to implement a data access layer( a Java class created for talking to a database). So we can create a new interface and call it UserRepository, generally you should create a repository for each model object in your database. Our repository will look like this:
```
public interface UserRepository extends JpaRepository<Users, Long> {
    
    @Query(value = "SELECT * FROM Users WHERE Users.username = ?1",nativeQuery = true)
    public Users findUserByUserName(String username);
}
```

- From the code above your first question probably is, Why an interface, can't we just use a class? And my honest answer is, an interface is simpler. An interface allows us to use the predefined methods Sprig gives us and we don't have to register it as a bean(more on beans later). The next question being, What is the `JpaRepository`, well it is an extension from the `Repository` interface . Which really means that it is a premade interface that gives us methods and handles the bean registration for us. `Users` and `Long` are used for the predefined methods that `JpaRepository` gives us.

### @Query
- With this annotation and the `nativeQuery = true` we have created a `Native Query`. Which means we create Java methods and have them run SQL statements when they are called.

###SQL
- So lets break down this SQL statement down a little

 `SELECT * FROM Users WHERE Users.username = ?1`

-  `SELECT` is used to signify that we are about to execute a query on a database table. the `*` is used to mean all, so `SELECT *` should be read as `SELECT ALL`. `FROM` is used to indicate which table is being queried. `WHERE` is used to indicate a conditional filter and `Users.username = ?1` is the filter. The `?1` is how we specify to use the username parameter in the findUserByUserName method

###Implementing the logic
- Now that we have the repository implemented we can move back to the `CustomUserDetailsService` class and implement the logic for the loadUserByUsername. The full implementation looks like this:
```
 @Autowired
    private UserRepository userRepository;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Users returnedUser = userRepository.findUserByUserName(username);
        if(returnedUser == null){
            throw new UsernameNotFoundException("USERNAME NOT FOUND");
        }
        UserDetails securityUser = new SecurityUser(returnedUser);
        return securityUser;
    }
```
####@Autowired
- Notice this annotation above the userRepository field. Any field  annotated with this is`injected` right after construction of the bean(more on beans later). What I means when I say `injected` is dependency injection and if you are unfamiliar with dependency injection then just give it a quick google. But basically know that when this class gets instantiated by Spring(covered in our bean section) an instance of `UserRepository` will get placed in this field. So that means that as long as userRepository is annotated with `@Autowired ` we can treat it just like a normal instance of the class.
- For the actual logic of the code, its pretty straight forward. The only thing that might seem confusing is the `SecurityUser` and That was a class created in the part one of this tutorial. [HERE](https://github.com/thePlebDev/Spring-security-examples/blob/master/src/main/java/com/example/demo/auth/SecurityUser.java) is the GitHub for the code.

###Registering CustomUserDetailsService as a Bean
- So first lets create a class called `ProjectConfig` and annotate it with `@Configuration `. This annotation means that this class is responsible for creating beans in the `Inversion of Control`(IOC) container. The IOC container is basically a part of the Spring that is responsible for creating and maintaining the life cycle of all the objects in our app.

###Beans?
- Finally we get to talk about beans, What is a bean? They are the objects that form the backbone of our application and are managed by the Spring IOC container. So a bean is really just an object that is instantiated, assembled and managed by the IOC container. Now if we want to go into specifics the part of the IOC that is responsible for managing the beans is called the `BeanFactory`.


###Registering a Bean
- Now in order for us to use our `UserDetailsService` we have to register it with the IOC container(turn it into a bean). To do that we do this:
```
@Configuration
public class projectConfig {
    @Bean
    public UserDetailsService userDetailsService(){
        return new CustomUserDetailsService();
    }
}
```
- The `@Bean ` annotation tells spring to call this method and turn its returned object into a bean. Since the return type is 
`UserDetailsService ` and thanks to the power of polymorphism Spring Security will use our `CustomUserDetailsService` instance for future `UserDetailsService ` use.

###Conclusion
- Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on [Twitter](https://twitter.com/TristanJava).