Rest- Api mit HTTP BASIC Authentication

matze86

Bekanntes Mitglied
Ich würde gerne eine Rest- Api mit HTTP BASIC Authentication erstellen, soweit habe ich mich eingelesen, aber bei der Umsetzung musste ich feststellen, das WebSecurityConfigurerAdapter nicht mehr aktuell ist. Gibt es dabei eine Alternative?
 

matze86

Bekanntes Mitglied
Der WebSecurityConfigurerAdapter gehört zu Spring. Willst du eine Spring Boot Anwendung erstellen? Oder eine Java EE? Oder irgendwas anders.
Ja ich habe schon eine spring Boot Anwendung und damit Rest gebaut.

Genau, das hatte ich auch schon in Betracht gezogen, nur ich finde in dem GitHub nicht die Klassen, wo es beschrieben wird.
 

KonradN

Super-Moderator
Mitarbeiter

LimDul

Top Contributor
Ganz wichtig ist auch - es gibt gerade einen Umbruch von Spring 5/Spring Boot 2 zu Spring 6/Spring Boot 3.

Fokussiere dich auf eine der beiden Varianten (5/2 oder 6/3) und schau dann auch genau nur nach diesen Versionen. Nicht kombinieren (Das führt nur zu Chaos). Daher auch wie @KonradN geschrieben hat auf die offiziellen Sachen schauen. Und bei externen Links schauen, für welche Version die sind.
 

matze86

Bekanntes Mitglied
Ich bin jetzt wie von @KonradN empfohlene https://spring.io/guides/gs/securing-web/ gefolgt und mir das 1:1 durchgearbeitet.
Soweit auch alles verstanden, nur da muss wieder was mit den Abhängigkeiten nicht stimmen.

Aber beim Ausführen bricht das Programm ab.

Ich werde noch verrückt mit den ganzen Abhängigkeiten, zumal aller paar Wochen/Monate was neues kommt. Da ist es als Junior schon sehr verwirrend.
Hier mal meine aktuelle pom.xml
XML:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>de.webauth</groupId>
    <artifactId>auth</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>auth</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
      
      
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity6</artifactId>
            <!-- Temporary explicit version to fix Thymeleaf bug -->
            <version>3.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
      
      
      
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Und bei der Klasse WebSecurityConfig ist in Zeile 16 "withDefaultPasswordEncoder()" durchgestrichen, heißt also veraltet wenn ich richtig bin.
Java:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((requests) -> requests.requestMatchers("/", "/home").permitAll().anyRequest().authenticated())
            .formLogin((form) -> form.loginPage("/login").permitAll()).logout((logout) -> logout.permitAll());

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user =
             User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(user);
    }
}
 

matze86

Bekanntes Mitglied
OK, es ist wieder eine Anwendung gelaufen, der Port war belegt obwohl ich aber immer auf Beenden gedrückt habe bis das rote Kästchen aus war.
Aber da bleibt immer noch das veraltete withDefaultPasswordEncoder().
 

KonradN

Super-Moderator
Mitarbeiter
In der Klasse wo man die spring Boot Anwendung startet?
Das ist eigentlich egal. Die Klasse muss gescannt werden, damit Spring Boot weiß, dass es da die Methode gibt, die so einen Bean erstellt.

Ich meine, ich hätte das in der Klasse drin gehabt, die auch die Security Config selbst hatte. Aber das ist nach meinem Verständnis egal.
 

matze86

Bekanntes Mitglied
Wenn ich die Methode
Java:
@Bean
public PasswordEncoder encoder() {
    return new BCryptPasswordEncoder();
}
eintrage, egal wo, dann kann ich mich nicht mehr einloggen.
 

KonradN

Super-Moderator
Mitarbeiter
Wenn ich die Methode
Java:
@Bean
public PasswordEncoder encoder() {
    return new BCryptPasswordEncoder();
}
eintrage, egal wo, dann kann ich mich nicht mehr einloggen.
Wie sieht denn Dein UserDetailsService nun aus? Hast Du immer noch den gleichen code da drin? Oder was machst Du da derzeit?

Du setzt jetzt ja einen PasswordEncoder und den musst Du dann auch beim Erstellen des Users verwenden. Also etwas wie:
Java:
        User.withUsername("user")
                .password(encoder.encode("password"))
                .roles("USER")
                .build();

Und encoder ist dann @Autowired PasswordEncoder encoder;

Hintergrund ist, dass Du das Passwort der Users natürlich richtig verschlüsseln musst.
 

matze86

Bekanntes Mitglied
Bisher hatte ich noch den alten code mit
Wie sieht denn Dein UserDetailsService nun aus? Hast Du immer noch den gleichen code da drin? Oder was machst Du da derzeit?
Bisher hatte ich noch den alten Code verwendet.


Jetzt habe ich mich durch die verlinkte gearbeitet. So wie ich es verstanden habe muss man folgendes machen:
Ich hab ja schon eine komplette Rest Api mit User, UserDTO, UserRepository und einen Controller.
Dazu erstelle ich eine interface Klasse IUserService die ein Integer erstellt und übergeben wird meine Klasse User.
Dann erstelle ich die Klasse UserServiceImpl und implementiere meine erstellte Klasse IUserService und zusätzlich noch UserDetailsService von org.springframework.security.core.userdetails.UserDetailsService.

In der Klasse wird dann das Passwort gesetzt.

Soweit denke ich mal ist das richtig, aber wo trage ich den Benutzername ein?

Das ganze soll so aussehen, wenn jemand mit sein RESTeasy client auf den UserDTO zugreift einen (beliebigen) Benutzername und auch Kennwort einzugeben.
 

matze86

Bekanntes Mitglied
Laut der Doku wurde eine User Klasse angelegt
Java:
public class User {
    
    @Id
    @GeneratedValue
    @Column(name="user_id")
    private Integer id;
    
    @Column(name="user_name")
    private String name;
    
    @Column(name="user_passwd")
    private String password;
    
    @Column(name="user_email")
    private String email;
    
    @ElementCollection(fetch= FetchType.EAGER)
    @CollectionTable(
            name="roles",
            joinColumns = @JoinColumn(name="user_id")
            )
    @Column(name="user_role")
    private List<String> roles;
    
}
und im Code der UserService
Java:
@Service
public class UserServiceImpl implements IUserService, UserDetailsService{
    
    @Autowired
    private UserRepository userRepo;
    
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Override
    public Integer saveUser(User user) {
        String passwd= user.getPassword();
        String encodedPasswod = passwordEncoder.encode(passwd);
        user.setPassword(encodedPasswod);
        user = userRepo.save(user);
        return user.getId();
    }
    
    @Override
    public UserDetails loadUserByUsername(String email)
            throws UsernameNotFoundException {
        
        Optional<User> opt = userRepo.findUserByEmail(email);
        
        if(opt.isEmpty())
                throw new UsernameNotFoundException("User with email: " +email +" not found !");
        else {
            User user = opt.get();
            return new org.springframework.security.core.userdetails.User(
                    user.getEmail(),
                    user.getPassword(),
                    user.getRoles()
                    .stream()
                    .map(role-> new SimpleGrantedAuthority(role))
                    .collect(Collectors.toSet())
            );
        }

und die UserRepository wurde mit
Java:
public interface UserRepository extends JpaRepository<User, Integer> {

    Optional<User> findUserByEmail(String email);
gefüllt.

Ist die User-Klasse für das Passwort bzw den ganzen login-Daten oder ist das schon der User für den Rest?
Meine UserRepository sieht z.B. so aus
Java:
public interface UserRepo extends JpaRepository<User, Long>{
    List<User> findByName(String lastName);
    User findById(long id);
}

Jetzt frage ich mich ob in der Methode loadUserByUsername der Klasse UserServiceImpl dort das Passwort gesetzt wird und ob ich eine User-Klasse für die log-Daten brauche?
 

matze86

Bekanntes Mitglied
Nach langen suchen für spring boot 3 und Security 6 habe ich nun folgende Klasse erstellt:

Java:
@Configuration
@EnableMethodSecurity
public class SecurityConfig {
    @Bean
    public static PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
        //http.csrf().disable().authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()).httpBasic(Customizer.withDefaults());
         http.authorizeHttpRequests().requestMatchers("/api/all").hasRole("USER").and().formLogin(Customizer.withDefaults()).httpBasic(Customizer.withDefaults());
        
        return http.build();
    }
    
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails matze = User.builder()
                .username("matze").password(passwordEncoder().encode("1"))
                .roles("USER").build();
        
        UserDetails admin = User.builder()
                .username("admin").password(passwordEncoder().encode("2"))
                .roles("ADMIN").build();
        
        return new InMemoryUserDetailsManager(matze, admin);
    }
In Zeile 11 und 12 kann man ja entweder es wie Zeile 11 machen und muss die @EnableMethodSecurity Annotation hinzufügen oder eben wie in Zeile 12 wo man den Pfad angibt.
Nun habe ich mal unter Docs geschaut, da gibt es ja so viele Methoden zum setzen von Eigenschaften.

Wie wäre eurer Meinung der beste Code an dieser Stele?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Rest mit Spring boot oder selbst anlegen Java Basics - Anfänger-Themen 14
I REST Api / JAX-RS, Swagger (OpenAPI) - generelle Starthilfen benötigt Java Basics - Anfänger-Themen 15
S Teilen ohne Rest Java Basics - Anfänger-Themen 15
tom.j85 Externe Rest API konsumieren Java Basics - Anfänger-Themen 9
S Konstruktor passt nicht zum Rest Java Basics - Anfänger-Themen 11
R Warum werden hier nur die grün und orangen Linien ausgegeben und der Rest unten nicht? Java Basics - Anfänger-Themen 5
D NodeJS Rest Api Erkläre Java Basics - Anfänger-Themen 3
B Methoden Element aus einem Array löschen, Rest nach vorne verschieben? Java Basics - Anfänger-Themen 4
J XML-Strukturen für REST-Service erstellen Java Basics - Anfänger-Themen 1
H Schleife für Teilen mit Rest Java Basics - Anfänger-Themen 1
I Höchste Zahl berechnen die eine Eingabe ohne Rest teilt und eine Primzahl ist Java Basics - Anfänger-Themen 2
D Rest ausrechnen Java Basics - Anfänger-Themen 2
J division mit rest Java Basics - Anfänger-Themen 8
F Teilen mit Rest Java Basics - Anfänger-Themen 12
O JRadioButton's - Einen aktivieren/ Rest deaktivieren Java Basics - Anfänger-Themen 5
M Rest herausfinden Java Basics - Anfänger-Themen 2
J Rest einer Zahl herausfinden Java Basics - Anfänger-Themen 3
L Webseite aufrufen (HTTP) Java Basics - Anfänger-Themen 8
P Maven-Dependencies (package org.apache.http.nio does not exist) Java Basics - Anfänger-Themen 6
S XML mittels HTTP Get Anfrage Java Basics - Anfänger-Themen 4
W Netwerkprogrammierung und Http Server Java Basics - Anfänger-Themen 10
R HTTP-Links in Java Class finden Java Basics - Anfänger-Themen 3
P Http Header, Http Proxy Java Basics - Anfänger-Themen 19
W HTTP-Stream auf Ajax umbauen Java Basics - Anfänger-Themen 7
F Http Post von mehreren Daten Java Basics - Anfänger-Themen 5
K URL ohne http:// Java Basics - Anfänger-Themen 8
F HTTP Get Queue Java Basics - Anfänger-Themen 7
J HTTP Request auf eine PHP Session Java Basics - Anfänger-Themen 1
E HTTP Client - Login durchführen? Java Basics - Anfänger-Themen 4
T Input/Output HTTP 403 aber im Browser gehts Java Basics - Anfänger-Themen 2
G Kraken HTTP Sniffer: ExceptionInInitializerError (Nutzt JNI) Java Basics - Anfänger-Themen 2
O get HTTP Headers Java Basics - Anfänger-Themen 5
L Methodenzerlegung HTTP Java Basics - Anfänger-Themen 4
S HTTP Adresse von offenem Browserfenset einlesen Java Basics - Anfänger-Themen 6
C HTTP POST-Request Java Basics - Anfänger-Themen 3
G http-Port beim Apache Tomcat ändern Java Basics - Anfänger-Themen 1
G HTTP Server Java Basics - Anfänger-Themen 2
S HTTP Request Umlaut Problem Java Basics - Anfänger-Themen 3
N Http-Request : Google Suche Java Basics - Anfänger-Themen 6
G http-Request auf Apache Tomcat Java Basics - Anfänger-Themen 13
G HTTP Body? Java Basics - Anfänger-Themen 4
A HTTP-Request Java Basics - Anfänger-Themen 15
K Problem mit javax/servlet/http/HttpServletRequest.java Java Basics - Anfänger-Themen 2
J Mehrdimensionales Array im Http-Request Java Basics - Anfänger-Themen 5
M Http Redirect Java Basics - Anfänger-Themen 5
M HTTP-Anfragen und Socket Java Basics - Anfänger-Themen 2
T mit einem string der form"[url]http://www.*.*/*"[/url] datei Java Basics - Anfänger-Themen 3
J HTTP Request Auslösen Java Basics - Anfänger-Themen 2
P HTTP-Request Parameter übergeben Java Basics - Anfänger-Themen 8
G http client Java Basics - Anfänger-Themen 4
G For Schleife-Basic Java Basics - Anfänger-Themen 11
B Rekursion Basic Java Basics - Anfänger-Themen 15
S Compiler-Fehler Basic- Taschenrechner/ Fehler Java Basics - Anfänger-Themen 8
S Basic- Taschenrechner? Java Basics - Anfänger-Themen 7
C Java Eingabeaufforderung-Basic Zwei Zahlen addieren Java Basics - Anfänger-Themen 2
M Java und Basic CVDMBF Java Basics - Anfänger-Themen 3
B Map, basic types & Object Java Basics - Anfänger-Themen 5
S Java Array Basic Java Basics - Anfänger-Themen 5
U Visual-Basic Programm mit Java steuern Java Basics - Anfänger-Themen 8
J Basic I/O ;-) Java Basics - Anfänger-Themen 11
J Reflection Basic Java Basics - Anfänger-Themen 26
P Very Basic Java Basics - Anfänger-Themen 5
P Äquivalent zu Visual Basic Collection Java Basics - Anfänger-Themen 6
2 rmi basic frage Java Basics - Anfänger-Themen 3
thE_29 visual basic verknüpfung in java Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben