Reputation: 949
I'm using spring boot security to help me to make authentication...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable().authorizeRequests()
.anyRequest().authenticated().and().httpBasic();
}
}
I have a rest service to make login (on my controller) thats a post request that i send email and password and i like to use this service to make the authentication...
But i'm new on spring-boot / java... Can some one help me to make that right way?
Thanks.
Upvotes: 2
Views: 4283
Reputation: 322
WebSecurityConfigurerAdaptor is deprecated now.
With Spring Security 6 and Spring boot 3, I implemented basic authentication like below:
@Configuration
@EnableWebSecurity
public class Config {
@Autowired private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
@Bean
UserDetailsService uds(PasswordEncoder pe) {
UserDetails user1 = User.withUsername("mohit")
.password(pe.encode("m123"))
.authorities("USER")
.build();
UserDetails user2 = User.withUsername("john").password(pe.encode("m123")).authorities("USER").build();
return new InMemoryUserDetailsManager(user1,user2);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.requestMatchers("/securityNone")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
//http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
MyAuthenticationEntryPoint looks like below:
@Component
public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
@Override
public void commence(
HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
throws IOException {
response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName() );
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status 401 - " + authEx.getMessage());
}
@Override
public void afterPropertiesSet() {
setRealmName("MyApplication");
super.afterPropertiesSet();
}
}
Upvotes: 0
Reputation: 280
Change add method in SpringSecurityConfig.java like Below
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserAuthenticationService userAuthenticationService;
@Autowired
private CustomAuthenticationProvider authenticationProvider;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(this.authenticationProvider).userDetailsService(this.userAuthenticationService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable().authorizeRequests()
.anyRequest().authenticated().and().httpBasic();
}}
Create CustomAuthenticationProvider.
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserAuthenticationService userAuthenticationService;
@Override
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String emailId = authentication.getName();
String password = (String) authentication.getCredentials();
UserDetails user = this.userAuthenticationService.loadUserByUsername(emailId);
if (user == null) {
throw new UsernameNotFoundException("Username not found.");
}
//Your password encoder here
if (!password.equals(user.getPassword())) {
throw new UsernameNotFoundException("Wrong password.");
}
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
return new UsernamePasswordAuthenticationToken(user, password, authorities);
}}
Create Custom UserService
@Service
public class UserAuthenticationService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
User user = userRepository.findByEmailAddressWithRole(email);
if (user == null) {
throw new UsernameNotFoundException("Username not found for " + email);
}
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
for (Role roles : user.getRoles()) {
grantedAuthorities.add(new SimpleGrantedAuthority(roles.getRoleName()));
}
return new UserAuthenticationWrapperDto(user.getId(), user.getEmailAddress(), user.getPassword(),
user.getUserType(), user.getCompany().getId(), grantedAuthorities,user.getName());
}}
Upvotes: 1
Reputation: 58094
You need to permit access to the login endpoint (at least). E.g.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/login", "/error").permitAll()
.antMatchers("/**").authenticated().and().exceptionHandling()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"));
}
If I were you I would remove the @EnableWebSecurity
(and let Spring Boot do it's job) as well. And then in the login endpoint you need to set the security context, e.g.
@PostMapping
public void authenticate(@RequestParam Map<String, String> map,
HttpServletRequest request, HttpServletResponse response) throws Exception {
Authentication result = authService.authenticate(map.get("username"), map.get("password"));
SecurityContextHolder.getContext().setAuthentication(result);
handler.onAuthenticationSuccess(request, response, result);
}
The authService
should throw BadCredentialsException
if the user cannot be authenticated. Here's a sample app that I used in a blog once: https://github.com/dsyer/mustache-sample/blob/7be8459173d0b65b6d44d05f86e581d358ea9b2e/src/main/java/com/example/DemoApplication.java#L177
Upvotes: 1