我目前正在大学里从事Spring Boot / Angular项目的工作。我正在努力与BCryptPasswordEncoder的matchs函数一起使用,该函数始终返回false。
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
private Long id;
@NotNull
@Column(unique = true)
private String userName;
@NotNull
private String password;
@ElementCollection(fetch = FetchType.EAGER)
List<Role> roles;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
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;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
}
@Autowired
PasswordEncoder passwordEncoder;
public User register(UserDto userDto) throws EntityExistsException {
User existingUser = userRepository.findUserByUserName(userDto.userName);
if (existingUser != null)
throw new EntityExistsException();
User newUser = new User();
newUser.setUserName(userDto.userName);
newUser.setPassword(passwordEncoder.encode(userDto.password));
List<Role> roles = new ArrayList<Role>();
roles.add(Role.ROLE_USER);
newUser.setRoles(roles);
try {
newUser = userRepository.save(newUser);
} catch (Exception e) {
return null;
}
return newUser;
}
public boolean credentialsAreCorrect(String username, String password){
User user = userRepository.findUserByUserName(username);
if ( user == null)
return false;
return passwordEncoder.matches(password, user.getPassword());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
在Angular中,我正在使用以下功能进行注册:
register() {
const userName = 'testUser';
const password = 'testPassword';
this.httpClient.post('http://localhost:8080/user/register', {userName, password})
.subscribe(value => console.log(value));
}
成功注册后,我将使用与UserService.credentialsAreCorrect()
方法相同的凭据。但是它总是返回false。 credentialsAreCorrect()
方法的参数正确,并且已找到用户。
调试服务器时,我注意到password
方法的credentialsAreCorrect(username, password)
参数的值始终为"PROTECTED"
。我坚信这只是调试时的视觉效果,但实际上值是"PROTECTED"
。
我从以下拦截器的请求标头中获得了密码:
@Component
public class AuthChannelInterceptor implements ChannelInterceptor {
private static final String USERNAME_HEADER = "login";
private static final String PASSWORD_HEADER = "passcode";
@Autowired
private WebSocketAuthenticatorService webSocketAuthenticatorService;
@Override
public Message<?> preSend(final Message<?> message, final MessageChannel channel) throws AuthenticationException {
final StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (StompCommand.CONNECT == accessor.getCommand()) {
final String username = accessor.getFirstNativeHeader(USERNAME_HEADER);
final String password = accessor.getFirstNativeHeader(PASSWORD_HEADER);
final UsernamePasswordAuthenticationToken user = webSocketAuthenticatorService.getAuthenticatedOrFail(username, password);
accessor.setUser(user);
}
return message;
}
}
答案 0 :(得分:0)
我终于通过将密码标题更改为usercode
来解决了该问题。我仍然不明白,为什么值会得到"PROTECTED"
,但至少它能起作用。
@Component
public class AuthChannelInterceptor implements ChannelInterceptor {
private static final String USERNAME_HEADER = "login";
private static final String PASSWORD_HEADER = "usercode";
@Autowired
private WebSocketAuthenticatorService webSocketAuthenticatorService;
@Override
public Message<?> preSend(final Message<?> message, final MessageChannel channel) throws AuthenticationException {
final StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (StompCommand.CONNECT == accessor.getCommand()) {
final String username = accessor.getFirstNativeHeader(USERNAME_HEADER);
final String password = accessor.getFirstNativeHeader(PASSWORD_HEADER);
final UsernamePasswordAuthenticationToken user = webSocketAuthenticatorService.getAuthenticatedOrFail(username, password);
accessor.setUser(user);
}
return message;
}
}
答案 1 :(得分:0)
我不确定是否已解决该问题,但这是我的5美分:而不是使用最终的String password = accessor.getFirstNativeHeader(PASSWORD_HEADER);您必须使用最终的String密码= accessor.getPasscode();因为不能直接访问StompHeaderAccessor.StompPasscode,即toString()产生“ PROTECTED”。如前所述,accessor.getFirstNativeHeader(“ XXXX”)适用于其他字段。 (据我了解,客户端将STOMP_PASSCODE_HEADER设置为“ PROTECTED”,这就是这种情况的原因)