Maintenant qu’on a une page register avec Workshop 2 : Création d’une page d’enregistrement (ajout backend), on peut maintenant logger nos utilisateurs !

On cherche à valider les utilisateurs lorsqu’ils appellent la méthode “/login”, et valider les utilisateurs pour tous les URL commençant par “/api/**”. Les mots de passe en BDD peuvent être chiffrés (BCrypt). On ajoute aussi les roles associés aux utilisateurs.
BasicAuthConfiguration, ajouter le contenu suivant.
@Configuration
@EnableWebSecurity
public class BasicAuthConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authenticationProvider());
}
@Override
protected void configure(HttpSecurity security) throws Exception {
security
// disable form login security (for login)
.csrf().disable()
// requests URL
.authorizeRequests()
.antMatchers("/api/**").authenticated()
// authentication type
.and().httpBasic()
// cors
.and().cors();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder());
provider.setUserDetailsService(userDetailsService);
return provider;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
configure, la partie cors est importante (en plus de CORS sur les controlleurs)authenticationProvider, c’est la classe qui ira chercher l’utilisateur en bdd (il va falloir créer le UserDetailsService)passwordEncoder, c’est le hashing du password, pe “test” -> “$2a$10$6MhOkqyfBeRf/tWx6bn/Ou6cVTdP2ZKMA.CmTdBnNyxCExbC3gAjy”UserController, ajouter login:
@GetMapping("/login")
public void login(@RequestBody UserDto user) {
userService.verifyUser(user.getUsername(), user.getPassword());
}
Role, pour les utilisateurs:
@Entity(name = "roles")
public class Role {
@Id
private String name;
@ManyToMany(mappedBy = "roles")
private List<User> users;
// ...
}
User, ajouter les roles:
@Entity(name = "users")
public class User {
@Id
private String username;
@Column
private String password;
@Column
private boolean enabled;
@ManyToMany
@JoinTable(
name = "user_roles",
joinColumns = @JoinColumn(name = "user_username"),
inverseJoinColumns = @JoinColumn(name = "role_name"))
private List<Role> roles;
// ...
}
UserDetailService, qui va charger en BDD l’utilisateur lors du login (utilisé dans la config de sécurité):
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findById(username)
.orElseThrow(() -> new UsernameNotFoundException("user not found " + username));
List<Role> roles = user.getRoles();
Set<GrantedAuthority> authorities = roles.stream()
.map(role -> new SimpleGrantedAuthority(role.getName()))
.collect(toSet());
return new org.springframework.security.core.userdetails.User(
user.getUsername(), user.getPassword(), authorities);
}
}
UserService, ajouter une méthode de validation du mot de passe pour l’utilisateur chargé par le UserDetailService:
@Override
public void verifyUser(String username, String password) {
UserDetails user = userDetailsService.loadUserByUsername(username);
if (!passwordEncoder.matches(password, user.getPassword())) {
throw new BadCredentialsException("bad credentials " + username);
}
}
TODO
import {Component, OnInit} from '@angular/core';
import {Router} from "@angular/router";
import {HttpClient} from "@angular/common/http";
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
model: any;
constructor(private http: HttpClient,
private router: Router) {
}
ngOnInit() {
this.model = {};
sessionStorage.setItem('token', '');
}
login() {
this.http
.post("http://127.0.0.1:8080/login", {
"username": this.model.username,
"password": this.model.password,
})
.subscribe(() => {
let base64hash = btoa(this.model.username + ':' + this.model.password);
sessionStorage.setItem('token', base64hash);
this.router.navigate(["/synths"])
},
error => {
alert(`Login failed: ${error}`)
})
}
}
Si l’authentification est réussie, on redirige vers la page racine des utilisateurs authentifés:

Rendez-vous à l’atelier suivant, Workshop 4 : Création d’un page de contenu authentifiée, pour ajouter du contenu à cette page.