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 kommt 'UserDetails' an Username und Passwort ran?
ich habe ein Problem mit der Implementierung der Klasse UserDetails. Ich habe den Username und Passwort des Users in PostgreSQL gespeichert und möchte ihn dadurch authentifizieren.
Java:
public class CustomUserDetails implements UserDetails {
private final User user;
public CustomUserDetails(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return this.user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Ich bekomme die Fehlermeldung
Cannot invoke "com.example.auth.User.getPassword()" because "this.user" is null
Ich verstehe ehrlich gesagt auch nicht, wie diese Klasse überhaupt an die Daten von Username und Passwort rankommen sollte, wenn diese in Controller definiert werden.
public CustomUserDetails(User user) {
this.user = user;
}
hier setzt du null ein und rufst dann null.getPassword() auf und das wirft die exception
warum sollte das passwort eigentlich jemals den server verlassen'? was will der user damit? der weis es doch , ansonsten hätte er sich nicht anmelden können
@yfons123 das Passwort sollte den Server ja auch nie verlassen. Mir geht es darum, den Username und das Passwort abzufangen, die an Controller gesendet werden.
Also im CustomUserDetailsService solltst du immer prüfen, ob user null ist um ggf. eine Exception zu werfen. Das hast Du in Deinem Code nicht. Es kann also schlicht daran scheitern, dass Du versuchst einen User zu authentifizieren, der nicht in der Datenbank ist.
Aber ich sehe bei Dir keine XML Konfiguration. Oder habe ich jetzt falsch geschaut?
Ich verstehe ehrlich gesagt auch nicht, wie diese Klasse überhaupt an die Daten von Username und Passwort rankommen sollte, wenn diese in Controller definiert werden.
Das erste brauchst Du nicht, denn SpringBoot scant ja die Packages ab der SpringBootApplication und findet den Bean.
Aber den password encoder und den authentication manager gibst Du nicht an so ich das richtig gesehen habe (Aber evtl. habe ich das auch einfach nur übersehen - im Webbrowser durch die Verzeichnisse zu gehen ist nicht optimal.
Und in Spring Boot würde ich das ohne XML machen ... und da hat man dann eine Methode wie:
Java:
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
Statt dem XML bean=passwordEncoder Teil
Und das mit dem Service würde dann so in der Art aussehen:
Java:
@Autowired
private CustomUserDetailsService userDetailsService;
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
Beider ist bei mir mit in einer Klasse - sonst geht das encoder() nicht ... wobei man das natürlich auch per AutoWire bekommen kann in einer anderen Klasse.
Also im CustomUserDetailsService solltst du immer prüfen, ob user null ist um ggf. eine Exception zu werfen. Das hast Du in Deinem Code nicht. Es kann also schlicht daran scheitern, dass Du versuchst einen User zu authentifizieren, der nicht in der Datenbank ist.
Nein, da liegst du komplett richtig. Ich versuche das Ganze ohne XML zu machen.
Ich habe nun encoder() und authProvider() in die Konfigurationsdatei eingepackt.
Wenn ich die Applikation nun laufen lasse, bekomme ich folgende Fehlermeldung:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customUserDetailService' defined in file [C:\Users\rsaad\IdeaProjects\auth\target\classes\com\example\auth\config\CustomUserDetailService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'userRepository' defined in com.example.auth.UserRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Not a managed type: class com.example.auth.User
Hattest Du nicht einen anderen Thread, in dem Dir schon zu der Persistence etwas gesagt wurde?
Schmeiße die Abhängigkeit raus, die Du diesbezüglich in Deinem POM hast. Spring Boot bringt diesbezüglich alles mit!
Damit hast Du kein javax.persistence mehr und das ändert sich zu jakarta.persistence.* (Ist ja Spring Boot 3, was Du da nutzen willst wenn ich das richtig gesehen habe!)
Und schon ist der Fehler weg - und du bekommst natürlich den nächsten
In der Klasse configurator hast Du nicht nur den Namen klein geschrieben sondern userDetailsService wird nie gesetzt, daher ein @Autowired setzen:
Java:
public class configurator {
@Autowired
private CustomUserDetailService customUserDetailService;