Giap Hiep

I'm Giap Hiep

I'm a web developer, a gymer. I enjoy share something i know that help people's work!
Giap Hiep

Cấu hình basic authencation trong spring boot

1. Thư viện

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

2. Cấu hình

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailServiceImpl userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //HTTP Basic authentication
                .httpBasic()
//                .and()
//                .sessionManagement()
//                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .csrf().disable()
                .formLogin().disable();
    }

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

    @Autowired
    public void globalUserDetails(final AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder);
    }
}
@Service
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) {
        UserEntity userEntity = userRepository.findByName(username)
                .orElseThrow(() -> new UsernameNotFoundException("username not found"));
        return new UserPrincipal(userEntity.getId(), userEntity.getName(), userEntity.getPassword(), new ArrayList<>());
    }
}
@Data
@Entity
@Table(name = "users")
public class UserEntity {
    @Id
    private Integer id;
    private String name;
    private String password;
}
@Data
public class UserPrincipal extends User {
    private Integer id;
    private String username;

    public UserPrincipal(Integer id, String username, String password, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, authorities);
        this.id = id;
        this.username = username;
    }
}
@ControllerAdvice
@Slf4j
public class AuthenSecurityControllerAdvice {

    @ModelAttribute
    public UserPrincipal customPrincipal(Authentication a) {
        return (UserPrincipal)(a == null ? null : a.getPrincipal());
    }
}
@RestController
@RequestMapping
@Log4j2
public class TestController {
    @GetMapping("/test")
    public String test(@ModelAttribute UserPrincipal principal) {
        log.info("User login information" + principal);
        return "oke";
    }
}

File application.yml

# SPRING
spring:
  # MYSQL CONFIG
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/auth_server?createDatabaseIfNotExist=true&useUnicode=yes&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: root
  # JPA CONFIG
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQLDialect
        format_sql: true

**script tạo databse auth_server **

CREATE DATABASE `auth_server`

DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `password` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
LOCK TABLES `users` WRITE;
INSERT INTO `users` VALUES (1,'noname','$2y$12$ivHcnAeTgcLA/fRmVnv.OuuqTDEqIOc9NcppprLPVVXvGRdJJz8bu'),(2,'noname2','$2y$12$ivHcnAeTgcLA/fRmVnv.OuuqTDEqIOc9NcppprLPVVXvGRdJJz8bu');
UNLOCK TABLES;

3. Test

Run ứng dụng lên và bắt đấu dùng postman để request

curl -X GET \
  http://localhost:8080/test \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Postman-Token: 994a23e3-38e6-42b2-ad1b-32a331450560'

Kết quả chúng ta không thể request và trả về lỗi 401 bởi vì chưa sử dụng basic authentication

Chúng ta sử dụng basic authentication ,hãy xem minh họa dưới đây

Chúng ta nhập user name , password (trong bảng users)

Các bạn để ý trong tab header chúng ta thấy Authorization đã được thêm vào với value Basic bm9uYW1lOjEyMzQ1Ng==

Kết qua như các bạn đã nhìn thấy chúng ta đã request được api /test

Sau khi bạn các bạn thực hiện request thành công thì trong postman sẽ xuất hiện cookies nó , map với 1 session ở trên server xác thực việc bạn đã authentication vì vậy ở lần request tiếp theo bạn sẽ không cần gắn Authorization vào header cho dến khi session hết hạn

Vậy là xong hẹn gặp lại các bạn trong bài viết tiếp theo.