Spring boot - /authenticate 端点不会返回 JSON Web Token

问题描述 投票:0回答:1

我已经为此工作了一段时间,我用来帮助我的视频是 2019 年的,所以它有点过时了,但我认为我可以解决这些问题。该程序运行但是当我尝试使用邮递员时我收到 401 未经授权的错误:

这里是jwtutil.java文件代码:

package com.stdbankjwtauth.authsystem.util;

import java.util.Map;
import java.util.function.Function;
import java.util.Date;
import java.util.HashMap;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@Service
public class JwtUtil {
    
private String SECRET_KEY = "secret";

public String extractUsername(String token) {
    return extractClaim(token, Claims::getSubject);
}

public Date extractExpiration(String token) {
    return extractClaim(token,Claims::getExpiration);
}

public <T> T extractClaim(String token, Function<Claims,T> claimsResolver) {
    final Claims claims = extractAllClaims(token);
    return claimsResolver.apply(claims);
}

private Claims extractAllClaims(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
}

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

public String generateToken(UserDetails userDetails) {
    Map<String,Object> claims = new HashMap<>();
    return createToken(claims,userDetails.getUsername());
}

private String createToken(Map<String,Object> claims, String Subject) {
return Jwts.builder().setClaims(claims).setSubject(Subject).setIssuedAt(new Date(System.currentTimeMillis()))
        .setExpiration(new Date(System.currentTimeMillis()+1000*60*60*10))
        .signWith(SignatureAlgorithm.HS256,SECRET_KEY).compact();
}

public boolean validateToken(String token, UserDetails userDetails){
    final String username = extractUsername(token);
    return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
}

AuthenticationRequest.java

package com.stdbankjwtauth.authsystem.models;

public class AuthenticationRequest {
    private String username;
    private String password;
    
    public AuthenticationRequest(String Username,String Password) {
        this.username = Username;
        this.password = Password;
    }
    
    public String getUsername() {
        return username;
    }
    public void setUsername(String Username) {
        this.username = Username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String Password) {
        this.password = Password;
    }
}

AuthenticationResponse.java

package com.stdbankjwtauth.authsystem.models;

public class AuthenticationResponse {
    private final String jwt;
    
    public AuthenticationResponse(String Jwt) {
        this.jwt = Jwt;
    }
    
    public String getJwt() {
        return jwt;
    }
}

AuthenticationEndpoint.java

package com.stdbankjwtauth.authsystem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.stdbankjwtauth.authsystem.models.AuthenticationRequest;
import com.stdbankjwtauth.authsystem.models.AuthenticationResponse;
import com.stdbankjwtauth.authsystem.util.JwtUtil;

@RestController
public class AuthenticateEnpoint {
    @Autowired
    private AuthenticationManager authenticationManager;
    
    @Autowired
    private UserDetailsService userDetailsService;
    
    @Autowired
    private JwtUtil jwtTokenUtil;
    
    @PostMapping("/authenticates")
    public ResponseEntity <?> createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) throws Exception{
        try {
            authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(),authenticationRequest.getPassword())
                );
        }catch(BadCredentialsException e) {
            throw new Exception("Incorrect username or password",e);
            }
        
        final UserDetails userDetails = userDetailsService
                .loadUserByUsername(authenticationRequest.getUsername());
        final String jwt = jwtTokenUtil.generateToken(userDetails);
        return ResponseEntity.ok(new AuthenticationResponse(jwt));
    }

}

安全配置器

package com.stdbankjwtauth.authsystem;

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.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.http.SessionCreationPolicy;

@Configuration
@EnableWebSecurity
public class SecurirtyConfigurer extends WebSecurityConfiguration {

    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.getDefaultUserDetailsService();
    }
    
    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .build();
    }
    protected void configure(HttpSecurity http) throws Exception{
        http
        .csrf()
        .disable()
        .authorizeHttpRequests().requestMatchers("/authenticates").permitAll()
        .anyRequest().authenticated()
        .and().sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
    
    
}

FileBasedAuthSystem.java

package com.stdbankjwtauth.authsystem.services;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.ArrayList;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.stereotype.Service;

@Configuration
@Service
public class FileBasedUserDetailsService {
    private static final String FILE_PATH = "C:\\repos\\STDBank-JWT-Auth-System\\stdbank-jwt-auth\\credentials.txt";
    
    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        List<String> lines = new ArrayList<>();
        try {
            lines = Files.readAllLines(Paths.get(FILE_PATH));
        }catch (Exception e) {
            e.printStackTrace();
        }
        for (String line : lines) {
            String[] parts = line.split(":");
            PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
            UserDetails user = User.withUsername(parts[0])
                    .password(encoder.encode(parts[1]))
                    .roles("USER")
                    .build();
                
                return new InMemoryUserDetailsManager(user);
    }
        throw new UsernameNotFoundException("Username not found: "+ lines);
    }
}

这是我使用的 youtube 视频的链接https://www.youtube.com/watch?v=X80nJ5T7YpE&t=81s

This is the error I get in Postman

java spring-boot spring-boot-actuator restful-authentication spring-boot-maven-plugin
1个回答
0
投票

我也发现了同样的问题。尝试添加以下链接。

链接:https://www.codejava.net/coding/solved-java-lang-noclassdefounderror-javax-xml-bind-jaxbexception

© www.soinside.com 2019 - 2024. All rights reserved.