I am new to spring boot. I am trying to implement a simple spring boot security with userdetailsservice in Spring Tool Suite(STS).
Below is the controller I used:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@GetMapping("/")
public String home() {
return("<h1>Welcome</h1>");
}
@GetMapping("/user")
public String user() {
return("<h1>Welcome user</h1>");
}
}
And the Web security configuration code:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@EnableWebSecurity
public class AppSecureConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService userDetailsService;
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user").hasRole("USER")
.antMatchers("/").permitAll()
.and().formLogin()
.and().logout().permitAll();
}
@Bean
public PasswordEncoder getPasswordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
I gave all the required dependencies in pom.xml.
So, I have added below line in application.propperties file, and now system is not generating security password.
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
And I have included user details Service for credentials. Below is user detail service class
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;
@Service
public class MyuserDetails implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return new userPrincipal(s);
}
}
and userPrincipal class
import java.util.Arrays;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
public class userPrincipal implements UserDetails {
private static final long serialVersionUID = 1L;
private String userName;
public userPrincipal(String userName) {
this.userName = userName;
}
public userPrincipal() {
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
}
@Override
public String getPassword() {
// TODO Auto-generated method stub
return "pass";
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return userName;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
}
now, when I ran the application using http://localhost:8081/ url, it is giving "No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken".
I am using Spring tool suite(STS) to run this project. Can some one point out what am I doing wrong here?
CodePudding user response:
Do not exclude the entire SecurityAutoConfiguration
, instead if you want you should just exclude the org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
.
Alternatively, you can expose a UserDetailsService
bean that will do the same for you, and you can get rid of the configureGlobal
method, like so:
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.builder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
CodePudding user response:
Add this to your application.properties
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
And your class will look like this:
- Add @Configuration to the class (as suggested by M. Deinum)
- Specify the role for the user, otherwise you will get
java.lang.IllegalArgumentException: Cannot pass a null GrantedAuthority collection
@Configuration
@EnableWebSecurity
public class AppSecureConfig extends WebSecurityConfigurerAdapter {
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("{noop}" "pass").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/user").hasRole("USER")
.antMatchers("/").permitAll()
.and().formLogin()
.and().logout().permitAll();
}
}