Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Spring Security: Wie den User dynamisch authentifizieren?
Hallo, ich bin ziemlich verwirrt was die Authentifizierung angeht und hab einige Fragen.
So definiere ich die Rollen:
Java:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ApplicationSecurityConfig {
private final PasswordEncoder passwordEncoder;
@Autowired
public ApplicationSecurityConfig(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "index", "/css/*", "js/*").permitAll()
.antMatchers("/api/**").hasRole(STUDENT.name())
.anyRequest()
.authenticated()
.and()
.httpBasic();
return http.build();
}
@Bean
public InMemoryUserDetailsManager userDetailsManager() {
var annaSmith = User.builder()
.username("annasmith")
.password(passwordEncoder.encode("password"))
.roles("ADMIN")
.build();
var linda = User.builder()
.username("linda")
.password(passwordEncoder.encode("pass"))
.roles("USER")
.build();
var tom = User.builder()
.username("tom")
.password(passwordEncoder.encode("pass"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(annaSmith, linda, tom);
}
}
Und so sieht der Controller aus:
Java:
@GetMapping
@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_ADMINTRAINEE')")
public List<Student> getAllStudents() {
return STUDENTS;
}
Das klappt soweit sehr gut. Nur verstehe ich nicht, warum es funktioniert. Die Methode userDetailsManager() rufe ich ja nirgends auf. Heisst das, dass sich die Annotation @PreAuthorize selbstständig darum kümmert?
Mein Code ist ja momentan ziemlich statisch. Wie gehe ich vor, wenn ich das Ganze dynamisch haben möchte? Muss sich denn die Methode userDetailsManager() zwingend in der Config-Datei befinden, oder kann ich sie auch im Service vom Login nehmen?
Und muss der User denn jedesmal eine Rolle zugewiesen bekommen, wenn er sich einloggt? Macht es denn nicht mehr Sinn, wenn die Rolle beim Registrieren in der DB gespeichert wird?
Da ist eine @Bean Annotation dran. Damit läuft das alles über Dependency Injection.
Wenn sich ein Benutzer einloggt, sucht Springt eine Bean vom Typ UserDetailManager über die normalen Spring-Lookup Mechanismen. Und fragt dann darüber die User-Details ab. Wie die Implementierung deines UserDetailManager aussieht, bleibt dir überlassen. Es gibt auch viele Default-Implementierungen um z.B. in einem Active Directory oder Ldap oder ähnliches nachzuschlagen.
form.loginPage("/login") erwarte das per GET eine HTML-Seite/Form ausgeliefert wird. Dein Controller stellt aber nur ein POST auf /login zur Verfügung.
Wenn du eine loginPage konfigurierst, dann musst du auch eine bereitstellen, ansonsten einfach nur:
....and() .formLogin()
dann generiert Spring Boot selbst eine Login-Page.
die Namen der Parameter sind richtig aber Spring Boot erwartet, dass du die HTML-Header richtig zurücksendest, mindestens die Cookies.
@Oneixee5 mit formLogin() generiert Spring Boot für mich ein Formular. Dieses Formular möchte ich aber gar nicht haben.
Das Login-Formular erstelle ich mit Angular. Heisst das, dass ich die URL vom Frontend eingeben muss? Also so: .formLogin(form -> form.loginPage("http://localhost:4200/login") ?
@Oneixee5 mit formLogin() generiert Spring Boot für mich ein Formular. Dieses Formular möchte ich aber gar nicht haben.
Das Login-Formular erstelle ich mit Angular. Heisst das, dass ich die URL vom Frontend eingeben muss? Also so: .formLogin(form -> form.loginPage("http://localhost:4200/login") ?