我已经使用spring-data-rest创建了一个spring boot应用程序。
我的Rest API工作得很好。然后我导入了弹簧安全装置。在引用了许多Web资源之后,我也完成了配置。
但是,每次发送请求时,都会收到Bad Credential Error以下是我的代码
package com.innaun.model;
import org.springframework.data.rest.core.annotation.RestResource;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.HashSet;
import java.util.Set;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long userId;
@Column(unique = true, nullable = false)
private String username;
@NotNull
@RestResource(exported = false )
private String password;
@NotNull
private boolean enabled;
@OneToMany
private Set<UserRole> userRoles = new HashSet<UserRole>(0);
public User() {
}
public User(String username, String password, boolean enabled) {
this.username = username;
this.password = password;
this.enabled = enabled;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
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 boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
package com.innaun.model;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
public class UserRole {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long userRoleId;
@NotNull
private String userRole;
@ManyToOne
private User user;
public UserRole() {
}
public UserRole(String userRole, User user) {
this.userRole = userRole;
this.user = user;
}
public Long getUserRoleId() {
return userRoleId;
}
public void setUserRoleId(Long userRoleId) {
this.userRoleId = userRoleId;
}
public String getUserRole() {
return userRole;
}
public void setUserRole(String userRole) {
this.userRole = userRole;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
package com.innaun.model;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource
public interface UserRepository extends CrudRepository<User, Long>{
User findByUsername(@Param("user") String user);
}
package com.innaun.model;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource
public interface UserRoleRepository extends CrudRepository<UserRole, Long> {
}
package com.innaun.model;
import com.innaun.model.UserRepository;
import com.innaun.model.UserRole;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service("appUserDetailsService")
public class AppUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Transactional
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
com.innaun.model.User user = userRepository.findByUsername(s);
List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRoles());
return buildUserForAuthentication(user, authorities);
}
private User buildUserForAuthentication(com.innaun.model.User user, List<GrantedAuthority> authorities){
return new User(user.getUsername(), user.getPassword(), user.isEnabled(), true, true, true, authorities);
}
private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles){
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
for (UserRole userRole : userRoles){
setAuths.add(new SimpleGrantedAuthority(userRole.getUserRole()));
}
List<GrantedAuthority> result = new ArrayList<GrantedAuthority>(setAuths);
return result;
}
}
package com.innaun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class ApplicationRESTSecurity extends WebSecurityConfigurerAdapter {
@Qualifier("appUserDetailsService")
@Autowired
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and().httpBasic()
.and().csrf()
.disable();
}
}
另外,我已添加以下内容将测试用户添加到数据库
package com.innaun;
import com.innaun.model.User;
import com.innaun.model.UserRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class PitchuApplication {
public static void main(String[] args) {
SpringApplication.run(PitchuApplication.class, args);
}
@Bean
CommandLineRunner init(UserRepository userRepository) {
return (args) -> {
userRepository.save(new User("myuser", "mypassword", true));
};
}
}
正如我想的那样,数据库现在拥有上述用户并启用了用户。
Screenshot of the User data table
所有其他表格都是空白的。
然而,当我尝试卷曲时
curl -u myuser:mypassword localhost:8080
它返回了
{"timestamp":1489090315435,"status":401,"error":"Unauthorized","message":"Bad credentials","path":"/"}
任何人都可以解释我哪里出错了。
答案 0 :(得分:0)
您的配置对我来说很好。所以,我最好的猜测是数据库中的password
列的长度小于60,这是散列BCrypt
将产生的长度。
答案 1 :(得分:0)
我明白了。这是如此简单的错误。我用来在userRepository中保存新用户的密码是raw而不是加密的。我想通了:
//Create a new password encoder
private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
//Encode the password
String password = "mypassword";
String hashedPassword = passwordEncoder.encode(password);
//Create the user with the encoded password
User user = new User(myuser, hashedPassword, true);
//then persist
userRepository.save(user);