[JAVA] Use Basic Authentication with Spring Boot

Introduction

Somehow, I wrote it in a style for SIer. The environment is also Java 1.7.

Overview

The method of Basic authentication in Spring Boot is explained using sample code. Assuming the usage scene as WebAPI, the setting is set to support stateless communication.

Presupposed environment

version

Version
Java 1.7
Spring Boot 1.5.9.RELEASE

Dependencies

Sample code

Setting

Make the following settings in JavaConfig. Refer to the comments in the source code for specific settings.

--Spring Security settings --Basic authentication --Settings for stateless communication --Bean definition - userDetailsService - passwordEncoder

MyConfigure.java


@Configuration
public class MyConfigure extends WebSecurityConfigurerAdapter {

  // ----------------------------------------
  //Spring Security settings
  // ----------------------------------------

  // <<<* Please note that WebSecurityConfigurerAdapter has multiple configure overload methods.>>>
  @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { super.configure(auth); }
  @Override public    void configure(WebSecurity                  web)  throws Exception { super.configure(web); }
  //---

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    //Basic authentication settings
    http.httpBasic().realmName("My sample realm");
    //Setting requests that require authentication
    http.authorizeRequests().anyRequest().authenticated();
    //If CSRF measures are enabled, POST without Token will result in an error, so disable it.
    http.csrf().disable();
    //Authentication information is always obtained from the Authorization header, so session management using cookies is not required.
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  }

  // ----------------------------------------
  //Bean definition
  // ----------------------------------------

  @Bean
  public UserDetailsService userDetailsService() {
    return new LoginPrincipal.LoginPrincipalService();
  }

  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }

}

Authentication information

Credentials are defined as a class that implements ʻUserDetails [^ fqdn-1](LoginPrincipal`). This class should be designed with the following points in mind.

--Keep only the information required for authentication --Define "user" information required for business separately from this class --Clarify the meaning of * username * in ʻUserDetails`

Based on the above, this sample has the following design.

-Hold "Login ID" in * username * --Hold "employee number" in addition to ʻUserDetails` information

ʻBy defining the implementation class of UserDetailsService [^ fqdn-2] as a bean, you can define the implementation when Spring Security searches for credentials (LoginPrincipal.LoginPrincipalService). This class is defined as an inner class of LoginPrincipal` for code simplification.

In the LoginPrincipal.DB class, dummy processing is defined to enable the sample code to operate alone.

LoginPrincipal.java


// ======================================================================
//* UserDetails implementation class
// ======================================================================
public class LoginPrincipal extends org.springframework.security.core.userdetails.User {
  // ※loginId(Login ID)Is super.Keep in username
  private final String employeeNumber; //employee number

  public LoginPrincipal(String loginId, String employeeNumber, String encodedPassword, String[] roles) {
    super(loginId, encodedPassword, true, true, true, true, AuthorityUtils.createAuthorityList(roles));
    this.employeeNumber = employeeNumber;
  }

  public String getLoginId() {
    return super.getUsername();
  }

  // <<< Getter >>>
  public String getEmployeeNumber() { return this.employeeNumber; }
  //---

  // ======================================================================
  //* Implementation class of UserDetailsService
  // ======================================================================
  public static class LoginPrincipalService implements org.springframework.security.core.userdetails.UserDetailsService {

    /**
     *Search for credentials with the specified login ID.
     *If no credentials are found, the result is{@code null}is.
     */
    public LoginPrincipal findByLoginId(String loginId) {
      //* Actually, the authentication information is obtained from the DB here.
      return DB.AUTH_TABLE.get(loginId);
    }

    /** {@inheritDoc} */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      //* For username, the "user name" for basic authentication is set by the authentication function of Spring Security.
      //Delegated to findByLoginId
      LoginPrincipal found = this.findByLoginId(username);
      if (found == null) {
        throw new UsernameNotFoundException("username not found: " + username);
      }
      return found;
    }
  }


  // ======================================================================
  // (For samples)Hold user authentication information in Map as an alternative to user authentication master
  // ======================================================================
  private static class DB {
    public static final Map<String, LoginPrincipal> AUTH_TABLE = new HashMap<>();

    static {
      BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
      LoginPrincipal[] data = { //
          new LoginPrincipal("U001", "S000001", passwordEncoder.encode("pass1"), new String[] { "USER" }), //
          new LoginPrincipal("U002", "S000002", passwordEncoder.encode("pass2"), new String[] { "USER" }), //
      };
      for (LoginPrincipal d : data) {
        AUTH_TABLE.put(d.getLoginId(), d);
      }
    }
  }

}

Basic authentication is now enabled. The following is a sample that refers to the authentication information from the Controller.

MyController.java


@RestController
public class MyController {

  @GetMapping
  public String index() {
    SecurityContext securityContext = SecurityContextHolder.getContext();
    LoginPrincipal loginPrincipal = (LoginPrincipal) securityContext.getAuthentication().getPrincipal();

    return "Hello " + loginPrincipal.getEmployeeNumber() + "!";
  }

}

in conclusion

This is my first Qiita post. I hope I can continue. Thank you for your guidance and encouragement.

Recommended Posts

Use Basic Authentication with Spring Boot
Achieve BASIC authentication with Spring Boot + Spring Security
Use Spring JDBC with Spring Boot
Execute arbitrary processing after Basic authentication with Spring boot.
Beginning with Spring Boot 0. Use Spring CLI
Use cache with EhCashe 2.x with Spring Boot
Download with Spring Boot
How to use MyBatis2 (iBatis) with Spring Boot 1.4 (Spring 4)
How to use built-in h2db with spring boot
Try LDAP authentication with Spring Security (Spring Boot) + OpenLDAP
[Introduction to Spring Boot] Authentication function with Spring Security
Generate barcode with Spring Boot
Hello World with Spring Boot
Basic Authentication with Java 11 HttpClient
Implement GraphQL with Spring Boot
Get started with Spring boot
Hello World with Spring Boot!
Run LIFF with Spring Boot
SNS login with Spring Boot
[Java] Thymeleaf Basic (Spring Boot)
File upload with Spring Boot
Spring Boot starting with copy
Spring Boot starting with Docker
Spring Boot + Springfox springfox-boot-starter 3.0.0 Use
Hello World with Spring Boot
Set cookies with Spring Boot
Add module with Spring Boot
Getting Started with Spring Boot
Create microservices with Spring Boot
Send email with spring boot
File upload with Spring Boot (do not use Multipart File)
Spring Boot + Java + GitHub authentication login
Implemented authentication function with Spring Security ②
gRPC on Spring Boot with grpc-spring-boot-starter
Implemented authentication function with Spring Security ③
Create an app with Spring Boot 2
Hot deploy with Spring Boot development
Database linkage with doma2 (Spring boot)
Spring Boot Tutorial Using Spring Security Authentication
Spring Boot programming with VS Code
Until "Hello World" with Spring Boot
Inquiry application creation with Spring Boot
Implemented authentication function with Spring Security ①
Get validation results with Spring Boot
Oauth2 authentication with Spring Cloud Gateway
(Intellij) Hello World with Spring Boot
Create an app with Spring Boot
Google Cloud Platform with Spring Boot 2.0.0
Use DBUnit for Spring Boot test
Check date correlation with Spring Boot
How to use ModelMapper (Spring boot)
I tried GraphQL with Spring Boot
[Java] LINE integration with Spring Boot
Use thymeleaf3 with parent without specifying spring-boot-starter-parent in Spring Boot
I tried Flyway with Spring Boot
Authentication / authorization with Spring Security & Thymeleaf
Message cooperation started with Spring Boot
Spring Boot gradle build with Docker
Processing at application startup with Spring Boot
Introducing Basic Authentication on Heroku [Spring Framework]
Hello World with Eclipse + Spring Boot + Maven