Rumah  >  Artikel  >  Java  >  Menjaga Perkhidmatan Mikro dengan Keselamatan Spring: Melaksanakan JWT

Menjaga Perkhidmatan Mikro dengan Keselamatan Spring: Melaksanakan JWT

PHPz
PHPzasal
2024-08-24 06:42:38398semak imbas

TOKEN WEB JSON (JWT)

JWT (JSON Web Token) ialah kaedah untuk menghantar maklumat dengan selamat antara dua pihak (seperti pelanggan dan pelayan) sebagai objek JSON. Ia direka bentuk agar padat dan selamat URL, menjadikannya mudah untuk dihantar dalam URL, pengepala.

  1. Pengepala
  2. Muat bayar
  3. Tandatangan

Pengepala
Pengepala biasanya terdiri daripada dua bahagian: jenis token (JWT) dan algoritma tandatangan yang digunakan, seperti HMAC SHA256 atau RSA.

{
"alg":"HS256",
"taip":"JWT"
}

Muat bayar
Di sinilah data sebenar disimpan. Ia boleh termasuk maklumat seperti ID pengguna, peranan, masa tamat tempoh dan tuntutan lain (data tentang pengguna atau sesi).

{
"e-mel":"ayushstwt@gmail.com",
"nama":"Ayush"
}

Tandatangan
Memastikan integriti token. Ini ialah ciri keselamatan yang memastikan token tidak diubah. Ia dicipta dengan menggabungkan pengepala dan muatan yang dikodkan dengan kunci rahsia menggunakan algoritma yang ditentukan. Tandatangan membantu pelayan mengesahkan bahawa token itu sah dan tidak diusik.

Faedah JWT

Tidak Perlu Menghantar Bukti Kelayakan Berulang: Dengan JWT, anda tidak perlu menghantar nama pengguna dan kata laluan anda dengan setiap permintaan. Sebaliknya, anda log masuk sekali, dan pelayan memberi anda token. Anda kemudian menghantar token ini dengan setiap permintaan untuk membuktikan identiti anda, menjadikan proses lebih selamat dan cekap.

Tamat Tempoh Terbina dalam: Setiap JWT disertakan dengan masa tamat, bermakna ia hanya sah untuk tempoh tertentu. Ini mengurangkan risiko penyalahgunaan jangka panjang jika token entah bagaimana dipintas. Selepas tamat tempoh, pengguna perlu log masuk semula untuk mendapatkan token baharu, menambah lapisan keselamatan tambahan.

JWT dengan Spring Boot menguruskan pengesahan pengguna dengan selamat dengan mengeluarkan token selepas log masuk. Token ini dihantar dengan setiap permintaan, memastikan komunikasi yang selamat dan tanpa kewarganegaraan tanpa menghantar bukti kelayakan berulang kali.

Komunikasi tanpa status bermakna pelayan tidak mengingati permintaan yang lalu. Setiap permintaan membawa semua yang diperlukan (seperti JWT), jadi pelayan tidak menyimpan maklumat sesi.

Melaksanakan JWT dalam aplikasi Java Spring Boot melibatkan beberapa langkah. Berikut ialah rangka ringkas untuk anda bermula:

1. Tambah Ketergantungan

Sertakan kebergantungan yang diperlukan dalam fail pom.xml anda

                <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.12.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.12.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.12.5</version>
            <scope>runtime</scope>
        </dependency>

Semua kebergantungan yang kita perlukan untuk mencipta aplikasi spring-boot dengan JWT

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.tier3Hub</groupId>
    <artifactId>user-auth-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-auth-service</name>
    <description>The user-auth-service is a microservice responsible for handling user authentication and authorization within a distributed system. It is designed to manage user login, registration, and secure access to various services using robust security practices. This service implements authentication mechanisms like JSON Web Tokens (JWT) and integrates with OAuth 2.0 for third-party authentication. Built with Spring Boot, it ensures scalability, reliability, and easy integration with other microservices in the system.</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>21</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.12.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.12.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.12.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>3.1.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

kami menggunakan pelbagai jenis kebergantungan seperti

  • Spring Boot Starter Actuator: 3.3.3 - Menambahkan ciri sedia pengeluaran seperti pemantauan dan pemeriksaan kesihatan.
  • Data Pemula But Spring JPA: 3.3.3 - Memudahkan interaksi pangkalan data dengan sokongan JPA.
  • Spring Boot Starter Security: 3.3.3 - Menyediakan ciri keselamatan seperti pengesahan dan kebenaran.
  • Spring Boot Starter Web: 3.3.3 - Menyokong membina aplikasi web, termasuk perkhidmatan RESTful.
  • API JJWT: 0.12.5 - Mengendalikan penciptaan dan penghuraian JWT untuk pengurusan token yang selamat.
  • Impl JJWT: 0.12.5 - Melaksanakan fungsi teras JWT.
  • JJWT Jackson: 0.12.5 - Mendayakan penghuraian JWT JSON menggunakan Jackson.
  • MySQL Connector: Runtime - Menyambungkan aplikasi anda ke pangkalan data MySQL.
  • Lombok: Tidak dinyatakan - Mengurangkan kod boilerplate dengan anotasi.
  • Spring Boot Starter Test: 3.3.3 - Menyediakan sokongan ujian untuk aplikasi Spring Boot.
  • Ujian Keselamatan Musim Bunga: 3.3.3 - Membantu dengan menguji konfigurasi keselamatan.
  • Pengesahan Pemula But Musim Bunga: 3.3.3 - Menambah sokongan pengesahan untuk objek permintaan dan respons.
  • SpringDoc OpenAPI Starter WebMVC UI: 2.5.0 - Mengintegrasikan Swagger UI untuk dokumentasi API.
  • ModelMapper: 3.1.1 - Memudahkan pemetaan objek antara lapisan yang berbeza.

*2. Struktur projek *

Securing Microservices with Spring Security: Implementing JWT

3. Tambahkan konfigurasi dalam fail application.properties

spring.application.name=user-auth-service

server.port=8000

spring.datasource.url=jdbc:mysql://localhost:3306/auth_services
spring.datasource.username=root
spring.datasource.password=ayush@123

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

#debug logs
logging.level.org.springframework.security=debug

spring.main.allow-circular-references=true 

4. Buat entiti PENGGUNA

package com.tier3Hub.user_auth_service.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@Table
@Entity(name = "User")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private String email;
    private String phoneNumber;
    private List<String> roles;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

** 5. cipta kelas perkhidmatan dan repositori serta antara muka**

Repository.java

package com.tier3Hub.user_auth_service.Repository;

import com.tier3Hub.user_auth_service.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface AuthRepository extends JpaRepository<User, Long> {

    User findByUsername(String username);
}

service.java

package com.tier3Hub.user_auth_service.service;

import com.tier3Hub.user_auth_service.dto.LoginResponse;
import com.tier3Hub.user_auth_service.dto.RegisterDTO;
import com.tier3Hub.user_auth_service.dto.RegisterResponse;

public interface AuthService {
    RegisterResponse register(RegisterDTO registerDTO);
}

6. buat DTO untuk permintaan log masuk dan log masuk serta respons

CreateloginDTO.java

package com.tier3Hub.user_auth_service.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class LoginDTO {
    @NotBlank(message = "Username is required")
    @Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters")
    private String username;

    @NotBlank(message = "Password is required")
    private String password;
}

loginResponse.java

package com.tier3Hub.user_auth_service.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class LoginResponse {
    private String accessToken;
    private String tokenType = "Bearer";
}

DaftarDTO.java

package com.tier3Hub.user_auth_service.dto;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class RegisterDTO {
    @NotBlank(message = "Username is required")
    @Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters")
    private String username;

    @NotBlank(message = "Password is required")
    @Size(min = 8, message = "Password must be at least 8 characters")
    private String password;

    @NotBlank(message = "Email is required")
    @Email(message = "Email should be valid")
    private String email;
}

RegisterResponse.java

package com.tier3Hub.user_auth_service.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class RegisterResponse {
    private Long id;
    private String username;
    private String email;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

*7. untuk menghantar respons tersuai daripada API kami menggunakan ResponseHandler.java *

package com.tier3Hub.user_auth_service.utils;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import java.util.HashMap;
import java.util.Map;

public class ResponseHandler {
    public static ResponseEntity<Object> generateResponse(String message, HttpStatus status, Object responseObj) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("message", message);
        map.put("status", status.value());
        map.put("data", responseObj);
        return new ResponseEntity<Object>(map, status);
    }

}

8. for storing some constants we create the class inside the utils package that is ApplicationConstants.java

package com.tier3Hub.user_auth_service.utils;

public class AppConstants {
    public static final String[] PUBLIC_URLS = { "/v3/api-docs/**", "/swagger-ui/**", "/api/auth/register/**", "/api/auth/login/**","/api/auth/registerAdmin/**" };
}

9. for converting the object one to another we use the dependency that is model mapper for configuration that we create the class inside the config package that is ApplicationConfigs.java

package com.tier3Hub.user_auth_service.config;

import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ApplicationConfigs {
    @Bean
    public ModelMapper modelMapper()
    {
        return new ModelMapper();
    }
}

**
This is the basic setup that we do for every spring-boot application we create now securing the rest endpoint with JWT we started.
**

now inside the security package we create the class called JWTFilter.java

The JWTFilter is a custom Spring Security filter that intercepts HTTP requests to validate JWTs. It checks for the "Authorization" header, extracts the token, and retrieves the username. If the token is valid, it creates an authentication token with user details and sets it in the security context, allowing the application to recognize the authenticated user for further processing.

package com.tier3Hub.user_auth_service.security;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Service;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Service
public class JWTFilter extends OncePerRequestFilter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JWTUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String authorizationHeader = request.getHeader("Authorization");
        String username = null;
        String jwt = null;
        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            username = jwtUtil.extractUsername(jwt);
        }
        if (username != null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (jwtUtil.validateToken(jwt)) {
                UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(auth);
            }
        }
        chain.doFilter(request, response);
    }
}

create the class JWTUtil.java

The JWTUtil class manages JWT operations, including extracting usernames and expiration dates from tokens. It generates new tokens using a secret key and validates existing tokens by checking their expiration. The class uses HMAC for signing and includes methods to parse claims and determine if tokens are expired, ensuring secure authentication and authorization in the application.

package com.tier3Hub.user_auth_service.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Service;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class JWTUtil {

    private String SECRET_KEY = "TaK+HaV^uvCHEFsEVfypW#7g9^k*Z8$V";

    private SecretKey getSigningKey() {
        return Keys.hmacShaKeyFor(SECRET_KEY.getBytes());
    }

    public String extractUsername(String token) {
        Claims claims = extractAllClaims(token);
        return claims.getSubject();
    }

    public Date extractExpiration(String token) {
        return extractAllClaims(token).getExpiration();
    }

    private Claims extractAllClaims(String token) {
        return Jwts.parser()
                .verifyWith(getSigningKey())
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }

    private Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    public String generateToken(String username) {
        Map<String, Object> claims = new HashMap<>();
        return createToken(claims, username);
    }

    private String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .claims(claims)
                .subject(subject)
                .header().empty().add("typ","JWT")
                .and()
                .issuedAt(new Date(System.currentTimeMillis()))
                .expiration(new Date(System.currentTimeMillis() + 1000 * 60 * 50)) // 5 minutes expiration time
                .signWith(getSigningKey())
                .compact();
    }

    public Boolean validateToken(String token) {
        return !isTokenExpired(token);
    }
}

*configure the Spring security and add some modifictaion we create the class SecurityConfig.java *

The SecurityConfig class sets up security for the application using Spring Security. It defines access rules, allowing public endpoints while restricting others based on user roles. The class incorporates a JWT filter to validate tokens and uses BCrypt for password encoding. It also configures an authentication manager with a custom user details service for secure user authentication.

package com.tier3Hub.user_auth_service.config;

import com.tier3Hub.user_auth_service.security.JWTFilter;
import com.tier3Hub.user_auth_service.service.UserInfoConfigManager;
import com.tier3Hub.user_auth_service.utils.AppConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Autowired
    private JWTFilter jwtFilter;

    @Autowired
    private UserInfoConfigManager userInfoConfigManager;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http.authorizeHttpRequests(request -> request
                        .requestMatchers(AppConstants.PUBLIC_URLS).permitAll()
                        .requestMatchers("/api/test/public/hello/**").hasAnyRole("USER","ADMIN")
                        .requestMatchers("/api/test/private/**").hasRole("ADMIN")
                        .anyRequest()
                        .authenticated())
                .csrf(AbstractHttpConfigurer::disable)
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userInfoConfigManager).passwordEncoder(passwordEncoder());
    }

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

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration auth) throws Exception {
        return auth.getAuthenticationManager();
    }
}

The securityFilterChain method configures access rules for different API endpoints in the Spring application. It permits public URLs and applies role-based access control for user and admin roles. Role-based authentication restricts resource access based on user roles (e.g., USER, ADMIN). In Spring Boot, you define roles and configure security settings in the SecurityConfig class to specify access permissions. During user registration, assign roles, and use annotations like @PreAuthorize to enforce role checks in controllers. This approach enhances security, allows easy permission management, and simplifies user access rights as the application scales. Implementing role-based auth provides flexibility and maintainability for your user management system. CSRF protection is disabled, and a custom JWT filter is added to authenticate requests based on JSON Web Tokens, ensuring secure and controlled access to resources.

configureGlobal method handle configures global authentication settings in a Spring application. It uses a custom user details service for loading user data and a BCrypt password encoder for secure password hashing. Additionally, it provides an AuthenticationManager bean for handling authentication processes, ensuring a secure and efficient user authentication system that leverages strong password management practices.

create the endpoints for register and login

package com.tier3Hub.user_auth_service.Controller;


import com.tier3Hub.user_auth_service.dto.LoginDTO;
import com.tier3Hub.user_auth_service.dto.LoginResponse;
import com.tier3Hub.user_auth_service.dto.RegisterDTO;
import com.tier3Hub.user_auth_service.security.JWTUtil;
import com.tier3Hub.user_auth_service.service.AuthService;
import com.tier3Hub.user_auth_service.service.UserInfoConfigManager;
import com.tier3Hub.user_auth_service.utils.ResponseHandler;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/auth")
public class AuthController {
    @Autowired
    JWTUtil jwtUtil;

    @Autowired
    AuthService authService;

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    private UserInfoConfigManager userInfoConfigManager;

    @PostMapping("/register")
    public ResponseEntity<Object> register(@Valid @RequestBody RegisterDTO registerDTO) {
        return ResponseHandler.generateResponse("User registered successfully", HttpStatus.OK, authService.register(registerDTO));
    }

    @PostMapping("/login")
    public ResponseEntity<Object> login(@Valid @RequestBody LoginDTO loginDTO) {
        try {
            Authentication authenticate = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(loginDTO.getUsername(), loginDTO.getPassword()));
            UserDetails userDetails = userInfoConfigManager.loadUserByUsername(loginDTO.getUsername());
            String jwt = jwtUtil.generateToken(userDetails.getUsername());
            LoginResponse loginResponse = LoginResponse
                    .builder()
                    .accessToken(jwt)
                    .build();
            return ResponseHandler.generateResponse("User logged in successfully", HttpStatus.OK, loginResponse);
        }
        catch (Exception e)
        {
            return new ResponseEntity<>("Incorrect username or password", HttpStatus.BAD_REQUEST);
        }
    }
}

This login method in the AuthController handles user login requests. It takes a LoginDTO containing the username and password, validates them, and attempts authentication using the AuthenticationManager. Upon successful authentication, it retrieves user details and generates a JWT token using the JWTUtil class. The token is then included in a LoginResponse object and returned with a success message. If authentication fails, it catches the exception and returns a "Incorrect username or password" response with a 400 status code.

generateToken(String username): This method creates an empty claims map and calls the createToken method with the username as the subject. It serves as the entry point for token generation.

c*reateToken(Map claims, String subject):* This method builds the JWT using the Jwts.builder(). It sets the claims, subject, and token metadata, such as issue date and expiration time (set to 5 minutes). The token is then signed with a secret key and compacted into a string format for transmission.

Testing

now we run the application

Securing Microservices with Spring Security: Implementing JWT

and hit the URL here our application is runing on 8000 port

http://localhost:8000/swagger-ui/index.html

Menggunakan Swagger dalam projek anda meningkatkan dokumentasi dan ujian API. Ia menyediakan antara muka mesra pengguna untuk pembangun meneroka API anda, memahami struktur permintaan/tindak balas dan menguji titik akhir terus daripada dokumentasi. Dengan menyepadukan Swagger, anda mendayakan penjanaan automatik dokumen API berdasarkan anotasi kod anda, menjadikannya lebih mudah bagi pembangun bahagian hadapan dan belakang untuk bekerjasama dengan cekap.

Securing Microservices with Spring Security: Implementing JWT

mula-mula kami daftarkan pengguna

Securing Microservices with Spring Security: Implementing JWT

kami mendapat sambutan seperti ini

Securing Microservices with Spring Security: Implementing JWT

selepas itu kami log masuk pengguna

Securing Microservices with Spring Security: Implementing JWT

kami mendapat sambutan seperti ini

Securing Microservices with Spring Security: Implementing JWT

Kesimpulan

Projek ini melaksanakan pengesahan berasaskan peranan menggunakan JWT (Token Web JSON) dalam aplikasi Spring Boot. Ia menampilkan mekanisme pengesahan selamat di mana pengguna boleh mendaftar dan log masuk, menerima JWT yang memberikan akses berdasarkan peranan yang diberikan mereka (seperti USER atau ADMIN). Kelas SecurityConfig mengkonfigurasi kebenaran akses, memastikan titik akhir awam boleh diakses oleh semua orang sambil mengehadkan operasi sensitif kepada pengguna yang dibenarkan sahaja. Kelas JWTUtil mengendalikan penciptaan token, pengesahan dan pengekstrakan pengguna. Secara keseluruhan, persediaan ini meningkatkan keselamatan, membolehkan kawalan akses yang lancar dan mantap merentas aplikasi.

Projek ini menggunakan rangka kerja keselamatan komprehensif yang memanfaatkan Spring Security untuk pengesahan dan kebenaran pengguna. AuthController memudahkan pendaftaran dan log masuk pengguna, menghasilkan JWT apabila pengesahan berjaya. Aplikasi ini menggunakan JWTFilter untuk memintas permintaan dan mengesahkan token, memastikan bahawa hanya pengguna yang disahkan boleh mengakses sumber yang dilindungi. Dengan menyepadukan kawalan akses berasaskan peranan, projek ini menyediakan sistem pengurusan pengguna yang fleksibel dan selamat. Reka bentuk ini bukan sahaja meningkatkan keselamatan tetapi juga meningkatkan pengalaman pengguna dengan meminimumkan keperluan untuk log masuk berulang. Secara keseluruhannya, ia meletakkan asas yang kukuh untuk membina perkhidmatan mikro berskala dan selamat.

Anda boleh menerokai kod sumber lengkap untuk Perkhidmatan Pengesahan Pengguna pada repositori GitHub saya. Projek ini mempamerkan pelbagai ciri seperti pendaftaran pengguna, log masuk dan akses selamat menggunakan JWT untuk pengesahan. Jangan ragu untuk menyemaknya, menyumbang atau menggunakannya sebagai rujukan untuk projek anda sendiri!

Repositori GitHub: https://github.com/ishrivasayush/user-auth-service

Bagi mereka yang berminat untuk menyelam lebih dalam ke JSON Web Token (JWT), saya syorkan melawati jwt.io. Sumber ini menyediakan maklumat komprehensif tentang JWT, termasuk cara ia berfungsi, strukturnya dan contoh praktikal. Ia merupakan titik permulaan yang sangat baik untuk memahami pengesahan dan kebenaran berasaskan token, yang penting untuk aplikasi web moden. Sama ada anda seorang pemula atau ingin menyegarkan pengetahuan anda, jwt.io menawarkan cerapan berharga dalam mengurus sesi pengguna dengan selamat.

Atas ialah kandungan terperinci Menjaga Perkhidmatan Mikro dengan Keselamatan Spring: Melaksanakan JWT. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Pengubah suai akses bahasa JavaArtikel seterusnya:Pengubah suai akses bahasa Java