Java 为基本身份验证、spring引导安全性获取多个用户
我有一个用户列表,我想在我的基本身份验证中使用它们 我的代码当前如下所示:Java 为基本身份验证、spring引导安全性获取多个用户,java,spring-boot,encoding,spring-security,bcrypt,Java,Spring Boot,Encoding,Spring Security,Bcrypt,我有一个用户列表,我想在我的基本身份验证中使用它们 我的代码当前如下所示: @Configuration @EnableWebSecurity public class BasicAuthConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();} @Autowired privat
@Configuration
@EnableWebSecurity
public class BasicAuthConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
@Autowired
private ConfigService configService;
// Authentication : User --> Roles
// NoOpPasswordEncoder has been deprecated in Spring security so {noop} is being used to avoid errors
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("someuser")
.password("somepassword")
.roles("USER");
}
// Authorization : Role -> Access
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and().authorizeRequests()
.antMatchers("/actuator/**")
.permitAll()
.antMatchers("/tokenservice/**")
.hasRole("USER")
.antMatchers("/")
.permitAll()
.and().csrf()
.disable()
.headers()
.frameOptions()
.and().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
auth.authenticationProvider(authenticationProvider());
}
public class SecUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository().findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
} else {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().getName()));
return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(),
grantedAuthorities);
}
}
}
我想用我的用户列表中的用户名和密码替换“someuser”和“somepassword”。目前,我可以使用configService.getCOnfigurations().getUsers()
获取列表。
用户只有用户名和密码,这两个字符串。如何将所有用户名和密码输入.withUser()
**编辑
我在configure中做了一个简单的for循环,应该可以,但是每当我尝试发布到我的API时,它都会说org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder:99-编码的密码看起来不像bcrypt
我使用在线bcrypt生成器生成密码,它们看起来像这样
<?xml version="1.0" encoding="UTF-8"?>
<Configurations>
<Port>8007</Port>
<EnableHttps>true</EnableHttps>
<KeyStorePath>classpath:ssl-server.jks</KeyStorePath>
<KeyPass>changeit</KeyPass>
<TokenTtlMillis>15000</TokenTtlMillis>
<Users Username="user1">
<Password>$2y$10$.8VQR6tJub5uVdVLByItQO8QYGZVuWPhLuBUTQSDJAvVpLAUmuqZ2</Password>
</Users>
<Users Username="user2">
<Password>$2y$10$r/CQz7PZp5banmSzr9OiDe2Kxrda4BhXIBXvvouRnm1w3M72wLQj.</Password>
</Users>
</Configurations>
8007
真的
类路径:ssl-server.jks
换
15000
$2y$10$.8VQR6TJU5UVDVLBYITQ8QYGZVUWPLUBUTQSDJAVVPLAUMUQZ2
$2y$10$r/CQz7PZp5banmSzr9OiDe2Kxrda4BhXIBXvvouRnm1w3M72wLQj。
密码是纯密码和密码2您可以在
Web安全配置适配器中声明DAOAuthenticationProvider
,如下所示:
@Configuration
@EnableWebSecurity
public class BasicAuthConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
@Autowired
private ConfigService configService;
// Authentication : User --> Roles
// NoOpPasswordEncoder has been deprecated in Spring security so {noop} is being used to avoid errors
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("someuser")
.password("somepassword")
.roles("USER");
}
// Authorization : Role -> Access
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and().authorizeRequests()
.antMatchers("/actuator/**")
.permitAll()
.antMatchers("/tokenservice/**")
.hasRole("USER")
.antMatchers("/")
.permitAll()
.and().csrf()
.disable()
.headers()
.frameOptions()
.and().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
auth.authenticationProvider(authenticationProvider());
}
public class SecUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository().findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
} else {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().getName()));
return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(),
grantedAuthorities);
}
}
}
并为它提供一个密码编码器
和一个用户详细信息服务
的实现,
为此,您必须实现相应的接口及其方法
然后,您可以在websecurityConfigureAdapter
类中指定您的authenticationProvider
,如下所示:
@Configuration
@EnableWebSecurity
public class BasicAuthConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
@Autowired
private ConfigService configService;
// Authentication : User --> Roles
// NoOpPasswordEncoder has been deprecated in Spring security so {noop} is being used to avoid errors
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("someuser")
.password("somepassword")
.roles("USER");
}
// Authorization : Role -> Access
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and().authorizeRequests()
.antMatchers("/actuator/**")
.permitAll()
.antMatchers("/tokenservice/**")
.hasRole("USER")
.antMatchers("/")
.permitAll()
.and().csrf()
.disable()
.headers()
.frameOptions()
.and().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
auth.authenticationProvider(authenticationProvider());
}
public class SecUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository().findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
} else {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().getName()));
return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(),
grantedAuthorities);
}
}
}
这样,您的UserDetailService
将提供所有可用的用户及其凭据,您不必在安全配置中担心这一点
通过这种方式,您可以以您想要的任何方式(简单文件、nosql DB,如MongoDB等)存储凭据,甚至可以更改该实现,而不会影响您使用spring security进行身份验证的方式
您的UserDetailService应该看起来像这样:
@Configuration
@EnableWebSecurity
public class BasicAuthConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
@Autowired
private ConfigService configService;
// Authentication : User --> Roles
// NoOpPasswordEncoder has been deprecated in Spring security so {noop} is being used to avoid errors
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("someuser")
.password("somepassword")
.roles("USER");
}
// Authorization : Role -> Access
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and().authorizeRequests()
.antMatchers("/actuator/**")
.permitAll()
.antMatchers("/tokenservice/**")
.hasRole("USER")
.antMatchers("/")
.permitAll()
.and().csrf()
.disable()
.headers()
.frameOptions()
.and().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
auth.authenticationProvider(authenticationProvider());
}
public class SecUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository().findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
} else {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().getName()));
return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(),
grantedAuthorities);
}
}
}
公共类SecUserDetailsService实现UserDetailsService{
@凌驾
public UserDetails loadUserByUsername(字符串用户名)引发UsernameNotFoundException{
User=userRepository().findByUsername(用户名);
if(user==null){
抛出新用户名NotFoundException(用户名);
}否则{
Set grantedAuthories=new HashSet();
添加(新的SimpleGrantedAuthority(user.getRole().getName());
返回新的org.springframework.security.core.userdetails.User(User.getName(),User.getPassword(),
授权机构);
}
}
}
这里我使用了一个UserRepository
,负责从您选择的存储中加载所有用户。例如,如果您决定将其存储在文件中,它将从文件中加载所有用户及其密码,并提供方法findByUsername
,如果找到具有匹配名称的User
对象,则返回该对象。如果需要,您的存储库还可以删除用户或修改他们的名称。您可以在WebSecurity配置适配器中声明DAOAuthenticationProvider
,如下所示:
@Configuration
@EnableWebSecurity
public class BasicAuthConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
@Autowired
private ConfigService configService;
// Authentication : User --> Roles
// NoOpPasswordEncoder has been deprecated in Spring security so {noop} is being used to avoid errors
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("someuser")
.password("somepassword")
.roles("USER");
}
// Authorization : Role -> Access
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and().authorizeRequests()
.antMatchers("/actuator/**")
.permitAll()
.antMatchers("/tokenservice/**")
.hasRole("USER")
.antMatchers("/")
.permitAll()
.and().csrf()
.disable()
.headers()
.frameOptions()
.and().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
auth.authenticationProvider(authenticationProvider());
}
public class SecUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository().findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
} else {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().getName()));
return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(),
grantedAuthorities);
}
}
}
并为它提供一个密码编码器
和一个用户详细信息服务
的实现,
为此,您必须实现相应的接口及其方法
然后,您可以在websecurityConfigureAdapter
类中指定您的authenticationProvider
,如下所示:
@Configuration
@EnableWebSecurity
public class BasicAuthConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
@Autowired
private ConfigService configService;
// Authentication : User --> Roles
// NoOpPasswordEncoder has been deprecated in Spring security so {noop} is being used to avoid errors
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("someuser")
.password("somepassword")
.roles("USER");
}
// Authorization : Role -> Access
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and().authorizeRequests()
.antMatchers("/actuator/**")
.permitAll()
.antMatchers("/tokenservice/**")
.hasRole("USER")
.antMatchers("/")
.permitAll()
.and().csrf()
.disable()
.headers()
.frameOptions()
.and().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
auth.authenticationProvider(authenticationProvider());
}
public class SecUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository().findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
} else {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().getName()));
return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(),
grantedAuthorities);
}
}
}
这样,您的UserDetailService
将提供所有可用的用户及其凭据,您不必在安全配置中担心这一点
通过这种方式,您可以以您想要的任何方式(简单文件、nosql DB,如MongoDB等)存储凭据,甚至可以更改该实现,而不会影响您使用spring security进行身份验证的方式
您的UserDetailService应该看起来像这样:
@Configuration
@EnableWebSecurity
public class BasicAuthConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
@Autowired
private ConfigService configService;
// Authentication : User --> Roles
// NoOpPasswordEncoder has been deprecated in Spring security so {noop} is being used to avoid errors
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("someuser")
.password("somepassword")
.roles("USER");
}
// Authorization : Role -> Access
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and().authorizeRequests()
.antMatchers("/actuator/**")
.permitAll()
.antMatchers("/tokenservice/**")
.hasRole("USER")
.antMatchers("/")
.permitAll()
.and().csrf()
.disable()
.headers()
.frameOptions()
.and().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
auth.authenticationProvider(authenticationProvider());
}
public class SecUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository().findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
} else {
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().getName()));
return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(),
grantedAuthorities);
}
}
}
公共类SecUserDetailsService实现UserDetailsService{
@凌驾
public UserDetails loadUserByUsername(字符串用户名)引发UsernameNotFoundException{
User=userRepository().findByUsername(用户名);
if(user==null){
抛出新用户名NotFoundException(用户名);
}否则{
Set grantedAuthories=new HashSet();
添加(新的SimpleGrantedAuthority(user.getRole().getName());
返回新的org.springframework.security.core.userdetails.User(User.getName(),User.getPassword(),
授权机构);
}
}
}
这里我使用了一个UserRepository
,负责从您选择的存储中加载所有用户。例如,如果您决定将其存储在文件中,它将从文件中加载所有用户及其密码,并提供方法findByUsername
,如果找到具有匹配名称的User
对象,则返回该对象。如果需要,您的存储库还可以删除用户或修改他们的姓名。基于Claudio的回答,使用DaoAuthenticationProvider
:
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService())
.authenticationProvider(authenticationProvider());
}
@Override
protected UserDetailsService userDetailsService() {
return new MyUserDetailsService();
}
UserDetailsService
是代码的真正核心所在。您将提供从XML读取的接口的自定义实现。假设您有一个方法getPassword(字符串用户名)
:
至于您的BCrypt问题,密码
散列给了我一个无效的salt修订错误。尝试直接使用应用程序对其进行哈希,例如:
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("password"));
}
或者在每行上传递一个带有密码的文件(使用Java 8):
publicstaticvoidmain(字符串[]args)引发IOException{
如果(args.length!=1){
System.out.println(“需要1个指向文件的参数”);
系统出口(1);
}
文件f=新文件(args[0]);
如果(!f.i.)