#java #spring #spring-boot #authentication #spring-security
#java #spring #spring-boot #аутентификация #spring-безопасность
Вопрос:
Я использую веб-токены Spring security и JSON для проверки электронной почты. Я заметил, что при регистрации нового сотрудника JWT не создается. Я использую электронную почту для входа в систему, а не имя пользователя. Я не знаю, связана ли эта проблема с интерфейсом Userdetalis. когда я пытаюсь войти в Postman, я получаю эту ошибку.
Мой код :
EmployeeController :
@CrossOrigin(origins = {"http://localhost:3000"})
@Tag(name = "Employee", description = "Employee API")
@RestController
@RequestMapping(EmployeeController.BASE_URL)
public class EmployeeController {
public static final String BASE_URL = "/api/v1/employees";
private final EmployeeService employeeService;
private final ConfirmationTokenService confirmationTokenService;
@Autowired
AuthenticationManager authenticationManager;
@Autowired
RoleRepository roleRepository;
@Autowired
PasswordEncoder encoder;
@Autowired
JwtUtils jwtUtils;
public EmployeeController(EmployeeService employeeService, ConfirmationTokenService confirmationTokenService) {
this.employeeService = employeeService;
this.confirmationTokenService = confirmationTokenService;
}
@GetMapping
@ResponseStatus(HttpStatus.OK)
public EmployeeListDTO getEmployeeList() {
return employeeService.getAllEmployees();
}
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody EmployeeDTO loginRequest) {
System.out.println("Hei");
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getEmail(), loginRequest.getPassword()));
System.out.println("Hei2");
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
System.out.println(jwt);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
List<String> roles = userDetails.getAuthorities().stream()
.map(item -> item.getAuthority())
.collect(Collectors.toList());
return ResponseEntity.ok(new JwtResponse(jwt,
userDetails.getId(),
userDetails.getEmail(),
roles));
}
@GetMapping({"/{id}"})
@ResponseStatus(HttpStatus.OK)
public EmployeeDTO getEmployeeById(@PathVariable Long id) {
return employeeService.getEmployeeById(id);
}
@PostMapping("/signup")
@ResponseStatus(HttpStatus.CREATED)
public EmployeeDTO createNewEmployee(@RequestBody EmployeeDTO employeeDTO) {
return employeeService.createNewEmployee(employeeDTO);
}
@PutMapping({"/{id}"})
@ResponseStatus(HttpStatus.OK)
public EmployeeDTO updateEmployee(@PathVariable Long id, @RequestBody EmployeeDTO employeeDTO){
return employeeService.saveEmployeeByDTO(id, employeeDTO);
}
@DeleteMapping({"/{id}"})
@ResponseStatus(HttpStatus.OK)
public void deleteEmployee(@PathVariable Long id){
employeeService.deleteEmployeeDTO(id);
}
}
> package com.tietoevry.bookorabackend.security.jwt;
>
> import com.tietoevry.bookorabackend.services.UserDetailsServiceImpl;
> import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.web.authentication.WebAuthenticationDetailsSource;
> import org.springframework.util.StringUtils; import
> org.springframework.web.filter.OncePerRequestFilter;
>
> import javax.servlet.FilterChain; import
> javax.servlet.ServletException; import
> javax.servlet.http.HttpServletRequest; import
> javax.servlet.http.HttpServletResponse; import java.io.IOException;
>
>
> public class AuthTokenFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsServiceImpl userDetailsService;
private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String jwt = parseJwt(request);
if (jwt != null amp;amp; jwtUtils.validateJwtToken(jwt)) {
String username = jwtUtils.getUserNameFromJwtToken(jwt);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
System.out.println("No JWT yet");
}
} catch (Exception e) {
logger.error("Cannot set user authentication: {}", e);
}
filterChain.doFilter(request, response);
}
private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");
if (StringUtils.hasText(headerAuth) amp;amp; headerAuth.startsWith("Bearer")) {
return headerAuth.substring(7, headerAuth.length());
}
return null;
} }
import java.util.List;
public class JwtResponse {
private String token;
private String type = "Bearer";
private Long id;
private String email;
private List<String> roles;
public JwtResponse(String accessToken, Long id, String email, List<String> roles) {
this.token = accessToken;
this.id = id;
this.email = email;
this.roles = roles;
}
public String getAccessToken() {
return token;
}
public void setAccessToken(String accessToken) {
this.token = accessToken;
}
public String getTokenType() {
return type;
}
public void setTokenType(String tokenType) {
this.type = tokenType;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<String> getRoles() {
return roles;
}
}
//generate Token
@Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
@Value("${bezkoder.app.jwtSecret}")
private String jwtSecret;
@Value("${bezkoder.app.jwtExpirationMs}")
private int jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
return Jwts.builder()
.setSubject((userPrincipal.getEmail()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() jwtExpirationMs))
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public String getUserNameFromJwtToken(String token) {
return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsServiceImpl userDetailsService;
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/h2-console/**").permitAll();
http.csrf().disable();
http.headers().frameOptions().disable();
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/v1/employees/**").permitAll()
.antMatchers("/api/test/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
и в intellj я получаю :
Комментарии:
1. Похоже, что предупреждение от bcrypt связано с закодированным паролем. Правильно ли закодирован ваш пароль в запросе?
2. Можете ли вы показать нам, как пароли выглядят в db, какая версия службы безопасности и сведений о пользователях?