0
0
Lập trình
Sơn Tùng Lê
Sơn Tùng Lê103931498422911686980

Hướng Dẫn Chi Tiết Cài Đặt Spring Security 6 với JWT và Oauth2 - Phần 4

Đăng vào 3 ngày trước

• 5 phút đọc

1. Giới thiệu về Spring Security và JWT

Trong bài viết này, chúng ta sẽ tiếp tục triển khai phần code liên quan đến bảo mật ứng dụng Spring Boot thông qua Spring Security 6 với sự hỗ trợ của JWT và OAuth2. Phần 4 này sẽ giúp bạn nắm rõ hơn về quy trình xác thực người dùng trong dự án của mình. Bạn có thể tham khảo lại nội dung của phần 3 tại đây: Phần 3 - Spring Security 6 với JWT và Oauth2.

2. Triển Khai Code Bảo Mật với Spring Security

Sau khi đã hoàn thành phần đăng ký trước đó, chúng ta cần cập nhật các thành phần liên quan đến bảo mật trong ứng dụng. Dưới đây là một số bước quan trọng.

2.1. Cập Nhật Entity User

Chúng ta sẽ cần cập nhật entity người dùng (User entity) để tích hợp với Spring Security. Điều này đòi hỏi chúng ta phải implement giao diện UserDetails để cung cấp thông tin người dùng và quyền hạn của họ. Đầu tiên, khai báo enum Role như sau:

java Copy
public enum Role {
    USER,
    ADMIN
}

Sau đó, cập nhật lại entity User:

java Copy
@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long userId;
    private String username;
    private String password;
    private String firstName;
    private String lastName;
    private String email;
    @Enumerated(EnumType.STRING)
    private Role role;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return List.of(new SimpleGrantedAuthority(role.name()));
    }

    @Override
    public boolean isAccountNonExpired() {
        return UserDetails.super.isAccountNonExpired();
    }
    
    @Override
    public boolean isAccountNonLocked() {
        return UserDetails.super.isAccountNonLocked();
    }
    
    @Override
    public boolean isCredentialsNonExpired() {
        return UserDetails.super.isCredentialsNonExpired();
    }
    
    @Override
    public boolean isEnabled() {
        return UserDetails.super.isEnabled();
    }
}

2.2. Cấu Hình Application

Để làm việc với các interface trong Spring Security, chúng ta cần phải tạo ra các instance của chúng và đánh dấu bằng annotation @Bean. Tạo lớp ApplicationConfiguration trong package config:

java Copy
@Configuration
@RequiredArgsConstructor
public class ApplicationConfiguration {
    private final UserRepository userRepository;

    @Bean
    public UserDetailsService userDetailsService() {
        return username -> userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
    }
    // Các bean khác sẽ được định nghĩa ở đây...
}

2.3. Triển Khai AuthenticationFilter

Chúng ta cần tạo lớp AuthenticationFilter, được kế thừa từ OncePerRequestFilter. Lớp này đảm bảo rằng phương thức doFilterInternal() chỉ được gọi một lần cho mỗi yêu cầu.

java Copy
@Component
@RequiredArgsConstructor
public class AuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(
            @NonNull HttpServletRequest request,
            @NonNull HttpServletResponse response,
            @NonNull FilterChain filterChain
    ) throws ServletException, IOException {
        final String authHeader = request.getHeader("Authorization");
        // Logic xử lý xác thực sẽ được thực hiện ở đây...
        filterChain.doFilter(request, response);
    }
}

2.4. Triển Khai JwtService và JwtServiceImpl

Tiếp theo là tạo interface JwtService và triển khai chúng trong JwtServiceImpl để trích xuất thông tin từ JWT:

java Copy
public interface JwtService {
    String extractUsername(String token);
    String generateToken(User user);
}

2.5. Cập Nhật AuthenticationFilter

Cập nhật nội dung phương thức doFilterInternal() trong lớp AuthenticationFilter để xác thực người dùng với token:

java Copy
@Override
protected void doFilterInternal(...){
    // Logic xác thực user qua JWT
}

2.6. Cập Nhật SecurityConfiguration

Cuối cùng, cập nhật SecurityConfiguration để thiết lập Spring Security cho ứng dụng:

java Copy
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {
    private final AuthenticationFilter authenticationFilter;
    private final AuthenticationProvider authenticationProvider;

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .cors(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests((authorize) -> authorize
                        .requestMatchers("/api/auth/**").permitAll()
                        .anyRequest().authenticated())
                .sessionManagement(session -> 
                        session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authenticationProvider(authenticationProvider)
                .addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}

2.7. Cập Nhật AuthenticationService

Chúng ta cần cập nhật lớp AuthenticationService để hỗ trợ logic đăng nhập và đăng ký với mã hóa mật khẩu:

java Copy
public interface AuthenticationService {
    AuthenticationResponse register(RegisterRequest request);
    AuthenticationResponse login(AuthenticationRequest request);
}

2.8. Cập Nhật AuthenticationController

Cuối cùng, cập nhật các controller để xử lý yêu cầu từ client:

java Copy
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthenticationController {
    private final AuthenticationService authenticationService;

    @PostMapping("/register")
    public ResponseEntity<AuthenticationResponse> register(@RequestBody RegisterRequest registerRequest) {
        AuthenticationResponse response = authenticationService.register(registerRequest);
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }

    @PostMapping("/login")
    public ResponseEntity<AuthenticationResponse> login(@RequestBody AuthenticationRequest request) {
        AuthenticationResponse response = authenticationService.login(request);
        return ResponseEntity.status(HttpStatus.OK).body(response);
    }
}

3. Kết Luận

Chúng ta đã hoàn thành việc thiết lập Spring Security với JWT và Oauth2 trong ứng dụng của mình. Bây giờ bạn có thể sử dụng Postman để thử nghiệm các chức năng đăng nhập, kiểm tra xác thực và bảo mật cho API của mình. Đảm bảo rằng token được quản lý và kiểm tra đúng cách. Nếu bạn gặp bất kỳ vấn đề nào, hãy theo dõi log để tìm hiểu nguyên nhân và xử lý kịp thời.
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào