Springboot中的JWT v2.4.5
Jwt in Springboot v2.4.5
我有这个 RestController:
@RestController
@Slf4j
public class AuthenticationRestController {
@Value("${jwt.header}")
private String tokenHeader;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private UserSecurityService userSecurityService;
@Autowired
private EmailService emailService;
@PostMapping(path = "/api/v1/auth", consumes = "application/json", produces = "application/json")
public ResponseEntity<JwtAuthenticationResponse>
createAuthenticationToken( @RequestBody JwtAuthenticationRequest authenticationRequest,
HttpServletRequest request) throws AuthenticationException {
LOG.info("authenticating {} " , authenticationRequest.getUsername());
authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());
...
/**
* Authenticates the user. If something is wrong, an {@link AuthenticationException} will be thrown
*/
private void authenticate(String username, String password) {
Objects.requireNonNull(username);
Objects.requireNonNull(password);
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
} catch (DisabledException e) {
e.printStackTrace();
throw new AuthenticationException("User is disabled!", e);
} catch (BadCredentialsException e) {
throw new AuthenticationException("Bad credentials!", e);
} catch (Exception e) {
e.printStackTrace();
}
}
}
但是我在登录时出现这个错误:
org.springframework.security.authentication.DisabledException: User is disabled
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider$DefaultPreAuthenticationChecks.check(AbstractUserDetailsAuthenticationProvider.java:331)
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:146)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:201)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:518)
at com.kispackp.security.controllers.AuthenticationRestController.authenticate(AuthenticationRestController.java:138)
和
@Entity
@Table(name="t_user")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable, UserDetails {
/** The Serial Version UID for Serializable classes. */
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(unique = true)
@JsonIgnore
private String username;
@JsonIgnore
private String password;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
}
当用户未启用时会发生此错误。接口 UserDetails
有一个名为 isEnabled
的方法,在验证用户时会检查它。
AbstractUserDetailsAuthenticationProvider.java
...
if (!user.isEnabled()) {
AbstractUserDetailsAuthenticationProvider.this.logger
.debug("Failed to authenticate since user account is disabled");
throw new DisabledException(AbstractUserDetailsAuthenticationProvider.this.messages
.getMessage("AbstractUserDetailsAuthenticationProvider.disabled", "User is disabled"));
}
...
您应该实施它,并且 return true
在用户启用的情况下,如下所示:
public class User implements Serializable, UserDetails {
... your current fields and methods
@Override
public boolean isEnabled() {
return true;
}
}
我有这个 RestController:
@RestController
@Slf4j
public class AuthenticationRestController {
@Value("${jwt.header}")
private String tokenHeader;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private UserSecurityService userSecurityService;
@Autowired
private EmailService emailService;
@PostMapping(path = "/api/v1/auth", consumes = "application/json", produces = "application/json")
public ResponseEntity<JwtAuthenticationResponse>
createAuthenticationToken( @RequestBody JwtAuthenticationRequest authenticationRequest,
HttpServletRequest request) throws AuthenticationException {
LOG.info("authenticating {} " , authenticationRequest.getUsername());
authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());
...
/**
* Authenticates the user. If something is wrong, an {@link AuthenticationException} will be thrown
*/
private void authenticate(String username, String password) {
Objects.requireNonNull(username);
Objects.requireNonNull(password);
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
} catch (DisabledException e) {
e.printStackTrace();
throw new AuthenticationException("User is disabled!", e);
} catch (BadCredentialsException e) {
throw new AuthenticationException("Bad credentials!", e);
} catch (Exception e) {
e.printStackTrace();
}
}
}
但是我在登录时出现这个错误:
org.springframework.security.authentication.DisabledException: User is disabled
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider$DefaultPreAuthenticationChecks.check(AbstractUserDetailsAuthenticationProvider.java:331)
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:146)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:201)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:518)
at com.kispackp.security.controllers.AuthenticationRestController.authenticate(AuthenticationRestController.java:138)
和
@Entity
@Table(name="t_user")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable, UserDetails {
/** The Serial Version UID for Serializable classes. */
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(unique = true)
@JsonIgnore
private String username;
@JsonIgnore
private String password;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
}
当用户未启用时会发生此错误。接口 UserDetails
有一个名为 isEnabled
的方法,在验证用户时会检查它。
AbstractUserDetailsAuthenticationProvider.java
...
if (!user.isEnabled()) {
AbstractUserDetailsAuthenticationProvider.this.logger
.debug("Failed to authenticate since user account is disabled");
throw new DisabledException(AbstractUserDetailsAuthenticationProvider.this.messages
.getMessage("AbstractUserDetailsAuthenticationProvider.disabled", "User is disabled"));
}
...
您应该实施它,并且 return true
在用户启用的情况下,如下所示:
public class User implements Serializable, UserDetails {
... your current fields and methods
@Override
public boolean isEnabled() {
return true;
}
}