英文:
404 status instead of returning a token! Why?
问题
I am writing a Spring MVC application using Hibernate and Spring Boot. I decided to connect Spring Security with JWT. I did everything according to the tutorial, but instead of returning the token as a result, I get a 404
status. Why? And how to fix it?
Configs:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void setJwtTokenProvider(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
// Fields
//
private JwtTokenProvider jwtTokenProvider;
//
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().disable().csrf().disable()
.httpBasic().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth/login").permitAll()
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider));
}
}
Controller:
@RequiredArgsConstructor
@RestController(value = "/auth")
public class AuthenticationController {
// Fields
//
private final AuthenticationManager authenticationManager;
private final JwtTokenProvider jwtTokenProvider;
private final UserService userService;
//
// GET-Methods
//
//
@PostMapping("/login")
public ResponseEntity<Map<String, String>> login(@RequestBody AuthenticationRequestDTO requestDto) {
try {
String login = requestDto.getLogin();
authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(login, requestDto.getPassword()));
User user = userService.findByLogin(login);
String token = jwtTokenProvider.createToken(login, user.getRole());
Map<String, String> response = new HashMap<>();
response.put("login", login);
response.put("token", token);
return ResponseEntity.ok(response);
} catch (AuthenticationException e) {
throw new BadCredentialsException("Invalid login or password");
}
}
}
JwtTokenProvider:
@Component
public class JwtTokenProvider {
// Fields
//
private final UserDetailsService userDetailsService;
@Value("${jwt.token.secret}")
private String secret;
@Value("${jwt.token.expired}")
private Long validityInMilliSeconds;
//
// METHODS
//
/**
* BCrypt
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(8);
}
@PostConstruct
protected void init() {
secret = Base64.getEncoder().encodeToString(secret.getBytes());
}
/**
* Generate TOKEN
*
* @param login
* @param role
* @return TOKEN
*/
public String createToken(String login, Role role) {
Claims claims = Jwts.claims().setSubject(login);
claims.put("roles", getRoleName(role));
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliSeconds);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
public Authentication getAuthentication(String token) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(getLogin(token));
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
public String getLogin(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
if (claims.getBody().getExpiration().before(new Date())) {
return false;
}
return true;
} catch (JwtException | IllegalArgumentException e) {
throw new JwtAuthenticationException("JWT token is expired or invalid");
}
}
public String resolveToken(HttpServletRequest req) {
String bearerToken = req.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer_")) {
return bearerToken.substring(7, bearerToken.length());
}
return null;
}
private String getRoleName(Role role) {
String roleName = role.name();
return roleName;
}
}
P.S. I enter the correct password
and login
, according to the entry in the database. If I enter another link, it will return 403
.
(So the problem is that I don't even pass this breakpoint! How can I get through it if I don't get to that place! I get a 404
error)
英文:
I am writing a Spring MVC application using Hibernate and Spring Boot. I decided to connect Spring Security with JWT. I did everything according to the tutorial, but instead of returning the token as a result, I get a 404
status. Why? And how to fix it?
Configs:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void setJwtTokenProvider(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}
// Fields
//
private JwtTokenProvider jwtTokenProvider;
//
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().disable().csrf().disable()
.httpBasic().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/auth/login").permitAll()
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider));
}
}
Controller:
@RequiredArgsConstructor
@RestController(value = "/auth")
public class AuthenticationController {
// Fields
//
private final AuthenticationManager authenticationManager;
private final JwtTokenProvider jwtTokenProvider;
private final UserService userService;
//
// GET-Methods
//
//
@PostMapping("/login")
public ResponseEntity<Map<String, String>> login(@RequestBody AuthenticationRequestDTO requestDto) {
try {
String login = requestDto.getLogin();
authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(login, requestDto.getPassword()));
User user = userService.findByLogin(login);
String token = jwtTokenProvider.createToken(login, user.getRole());
Map<String, String> response = new HashMap<>();
response.put("login", login);
response.put("token", token);
return ResponseEntity.ok(response);
} catch (AuthenticationException e) {
throw new BadCredentialsException("Invalid login or password");
}
}
}
JwtTokenProvider:
@Component
public class JwtTokenProvider {
// Fields
//
private final UserDetailsService userDetailsService;
@Value("${jwt.token.secret}")
private String secret;
@Value("${jwt.token.expired}")
private Long validityInMilliSeconds;
//
// METHODS
//
/**
* BCrypt
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(8);
}
@PostConstruct
protected void init() {
secret = Base64.getEncoder().encodeToString(secret.getBytes());
}
/**
* Generate TOKEN
*
* @param login
* @param role
* @return TOKEN
*/
public String createToken(String login, Role role) {
Claims claims = Jwts.claims().setSubject(login);
claims.put("roles", getRoleName(role));
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliSeconds);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
public Authentication getAuthentication(String token) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(getLogin(token));
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
public String getLogin(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
if (claims.getBody().getExpiration().before(new Date())) {
return false;
}
return true;
} catch (JwtException | IllegalArgumentException e) {
throw new JwtAuthenticationException("JWT token is expired or invalid");
}
}
public String resolveToken(HttpServletRequest req) {
String bearerToken = req.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer_")) {
return bearerToken.substring(7, bearerToken.length());
}
return null;
}
private String getRoleName(Role role) {
String roleName = role.name();
return roleName;
}
}
P.S. I enter the correct password
and login
, according to the entry in the database. If I enter another link, it will return 403
.
(So the problem is that I don't even pass this breakpoint! How can I get through it if I don't get to that place! I get a 404
error)
答案1
得分: 1
如果您未使用嵌入式Tomcat,请尝试在URL之前添加项目名称。例如:
http://localhost:8080/project-name/auth/login
英文:
if you are not using tomcat embedded, try to add the project name before your urls. ex :
http://localhost:8080/project-name/auth/login
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论