Java >> Java Tutorial >  >> Tag >> Spring

Hinzufügen einer Social-Anmeldung zu einer Spring MVC-Webanwendung:Konfiguration

In der guten alten Zeit meldeten sich Benutzer mit der Kombination aus Benutzername und Passwort an. Auch wenn manche Leute heutzutage immer noch den traditionellen Weg bevorzugen, möchten sich immer mehr Benutzer mit ihren Social-Media-Konten anmelden.

Dies macht Spring Social (und seine Unterprojekte) zu einer nützlichen Ergänzung des Spring-Projektportfolios. Die Integration von Spring Social mit Spring Security war jedoch etwas umständlich.

Spring Social 1.1.0 ändert all dies. Es bietet eine nahtlose Integration mit Spring Security, und die Java-Konfigurationsunterstützung von Spring Security lässt die Konfiguration wie einen Spaziergang im Park erscheinen.

Du musst mich nicht beim Wort nehmen. Lesen Sie weiter und Sie werden lernen, wie das gemacht wird.

Die Anforderungen unserer Lösung sind die folgenden:

  • Die Erstellung eines Benutzerkontos muss über ein normales Registrierungsformular möglich sein.
  • Es muss möglich sein, ein Benutzerkonto mit einem Social Sign-In zu erstellen.
  • Die Anmeldung mit Benutzername und Passwort muss möglich sein.
  • Die Anmeldung über einen SaaS-API-Anbieter muss möglich sein.
  • Die Anwendung muss Facebook und Twitter unterstützen.
  • Die Anwendung muss "normale" Spring MVC-Controller verwenden (kein REST).

Beginnen wir mit einem Blick auf die Voraussetzungen dieses Tutorials.

Voraussetzungen

Dieses Tutorial geht davon aus, dass Sie die von der Beispielanwendung verwendete Facebook- und Twitter-Anwendung bereits erstellt haben. Sie können diese Anwendungen erstellen, indem Sie diesen Links folgen:

  • Facebook-Entwickler
  • Twitter-Entwickler

Wenn Sie nicht wissen, wie das geht, können Sie sich die folgenden Links ansehen:

  • Facebook-Entwickler – Erstellen einer App-Detailseite (Wählen Sie „Website mit Facebook-Login“, wenn Sie gefragt werden, wie sich Ihre Anwendung in FB integrieren lässt).
  • So erstellen Sie eine Twitter-App in 8 einfachen Schritten (aktivieren Sie das Kontrollkästchen „Zulassen, dass diese Anwendung zum Anmelden mit Twitter verwendet wird“).

Lassen Sie uns weitermachen und herausfinden, wie wir die erforderlichen Abhängigkeiten mit Maven erhalten können.

Erforderliche Abhängigkeiten mit Maven erhalten

Das erste, was wir tun müssen, ist, die erforderlichen Abhängigkeiten mit Maven zu erhalten. Wir können dies tun, indem wir die folgenden Abhängigkeiten in unserer POM-Datei deklarieren:

  • Spring Security (Version 3.2.0.RELEASE).
    • Der Kern Modul enthält zentrale Authentifizierungs- und Zugriffskontrollkomponenten.
    • Die config -Modul enthält den Code zum Analysieren von XML-Konfigurationsdateien mithilfe des Spring Security-XML-Namespace.
    • Die Taglibs -Modul enthält die Spring Security JPS-Tag-Bibliotheken.
    • Das Web Modul enthält Filter und allen anderen Code, der sich auf die Websicherheit bezieht.
  • Apache HttpClient (Version 4.3.2). Apache HttpClient ist eine optionale (aber empfohlene) Abhängigkeit von Spring Social. Wenn es vorhanden ist, verwendet Spring Social es als HTTP-Client. Andernfalls verwendet Spring Social die standardmäßigen Java SE-Komponenten.
  • Spring Social (Version 1.1.0.RELEASE).
    • Die config -Modul enthält den Code zum Analysieren von XML-Konfigurationsdateien mithilfe des Spring Social XML-Namespace. Es fügt auch Unterstützung für die Java-Konfiguration von Spring Social hinzu.
    • Der Kern -Modul enthält das Connect-Framework und bietet Unterstützung für OAuth-Clients.
    • Die Sicherheit Modul integriert Spring Security mit Spring Social. Es delegiert die Authentifizierungsbelange, die normalerweise von Spring Security erledigt werden, an Dienstanbieter, indem es Spring Social verwendet.
    • Das Web Das Modul enthält Komponenten, die den Authentifizierungs-Handshake zwischen unserer Webanwendung und dem Dienstanbieter handhaben.
  • Spring Social Facebook (Version 1.1.0.RELEASE) ist eine Erweiterung von Spring Social und bietet Facebook-Integration.
  • Spring Social Twitter (Version 1.1.0.RELEASE) ist eine Erweiterung von Social Social, die Twitter-Integration bereitstellt.

Der relevante Teil der pom.xml Datei sieht wie folgt aus:

<!-- Spring Security -->
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-core</artifactId>
	<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-config</artifactId>
	<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-taglibs</artifactId>
	<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.security</groupId>
	<artifactId>spring-security-web</artifactId>
	<version>3.2.0.RELEASE</version>
</dependency>

<!-- Use Apache HttpClient as HTTP Client -->
<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
	<version>4.3.2</version>
</dependency>

<!-- Spring Social -->
<dependency>
	<groupId>org.springframework.social</groupId>
	<artifactId>spring-social-config</artifactId>
	<version>1.1.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.social</groupId>
	<artifactId>spring-social-core</artifactId>
	<version>1.1.0.RELEASE</version>
</dependency>
<dependency>     
	<groupId>org.springframework.social</groupId>
	<artifactId>spring-social-security</artifactId>
	<version>1.1.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.social</groupId>
	<artifactId>spring-social-web</artifactId>
	<version>1.1.0.RELEASE</version>
</dependency>
 
<!-- Spring Social Facebook -->
<dependency>
	<groupId>org.springframework.social</groupId>
	<artifactId>spring-social-facebook</artifactId>
	<version>1.1.0.RELEASE</version>
</dependency>
 
<!-- Spring Social Twitter -->
<dependency>
	<groupId>org.springframework.social</groupId>
	<artifactId>spring-social-twitter</artifactId>
	<version>1.1.0.RELEASE</version>
</dependency>

Als nächstes müssen wir eine Eigenschaftendatei für die Konfigurationseigenschaften unserer Anwendung erstellen. Lassen Sie uns herausfinden, wie das gemacht wird.

Erstellen der Eigenschaftendatei

Wir können die Eigenschaftendatei erstellen, indem wir diesen Schritten folgen:

  1. Erstellen Sie eine Datei namens application.properties und stellen Sie sicher, dass es im Klassenpfad gefunden wird.
  2. Datenbankverbindung konfigurieren.
  3. Ruhezustand konfigurieren.
  4. Fügen Sie die Facebook-Anwendungs-ID und das Anwendungsgeheimnis zur Eigenschaftendatei hinzu.
  5. Fügen Sie den Twitter-Consumer-Key und das Consumer-Secret zur Properties-Datei hinzu.

Der Inhalt von application.properties Datei sieht wie folgt aus:

#Database Configuration
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/socialtwitter
db.username=socialtwitter
db.password=password

#Hibernate Configuration
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.format_sql=true
hibernate.hbm2ddl.auto=validate
hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
hibernate.show_sql=false

#Facebook
facebook.app.id=foo
facebook.app.secret=bar

#Twitter
twitter.consumer.key=foo
twitter.consumer.secret=bar

Bevor wir unsere Anwendung konfigurieren können, müssen wir einige gemeinsame Komponenten erstellen. Lassen Sie uns herausfinden, was diese Komponenten sind und wie wir sie erstellen können.

Erstellung der gemeinsamen Komponenten

Wir müssen drei Komponenten erstellen, die während des Authentifizierungsprozesses verwendet werden. Diese Komponenten sind:

  • Wir haben eine Klasse erstellt, die die Benutzerdetails eines authentifizierten Benutzers enthält.
  • Wir müssen eine Klasse erstellen, die den UserDetailsService implementiert Schnittstelle. Diese Klasse wird verwendet, um Benutzerinformationen zu laden, wenn der Benutzer die Formularanmeldung verwendet.
  • Wir müssen eine Klasse erstellen, die den SocialUserDetailsService implementiert Schnittstelle. Diese Klasse wird verwendet, um Benutzerinformationen zu laden, wenn der Benutzer die soziale Anmeldung verwendet.

Lassen Sie uns weitermachen und herausfinden, wie wir diese Klassen implementieren können.

Erstellen der Benutzerdetailklasse

Wir müssen die folgenden Anforderungen berücksichtigen, wenn wir die Klasse erstellen, die die Benutzerdetails des authentifizierten Benutzers enthält:

  • Die Klasse, die die Benutzerdetails eines Benutzers speichert, der die Formularanmeldung verwendet, muss die UserDetails implementieren Schnittstelle.
  • Die Klasse, die die Benutzerdetails eines Benutzers speichert, der die soziale Anmeldung verwendet, muss die SocialUserDetails implementieren Schnittstelle.

Spring Social hat einen SocialUser Klasse, die diese beiden Anforderungen erfüllt. Oftmals möchten wir jedoch anwendungsspezifische Informationen zu unserer Benutzerdetailklasse hinzufügen.

Wir können dies tun, indem wir diesen Schritten folgen:

  1. Erstellen Sie die Benutzerdetailklasse.
  2. Erweitern Sie den SocialUser Klasse.
  3. Fügen Sie der erstellten Klasse anwendungsspezifische Felder hinzu. Die anwendungsspezifischen Felder unserer Beispielanwendung sind:id , Vorname , Nachname , Rolle und socialSignInProvider .
  4. Erstellen Sie einen Konstruktor, der den Benutzernamen, das Passwort und eine Sammlung gewährter Berechtigungen als Parameter verwendet. Übergeben Sie diese Parameter an den Konstruktor des SocialUser Klasse.
  5. Getter für anwendungsspezifische Felder erstellen.
  6. Fügen Sie eine innere Builder-Klasse hinzu, die verwendet wird, um neue ExampleUserDetails zu erstellen Objekte.

Der Quellcode unserer Benutzerdetails-Klasse sieht wie folgt aus:

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.social.security.SocialUser;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class ExampleUserDetails extends SocialUser {

    private Long id;

    private String firstName;

    private String lastName;

    private Role role;

    private SocialMediaService socialSignInProvider;

    public ExampleUserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, authorities);
    }

	//Getters are omitted for the sake of clarity.

    public static class Builder {

        private Long id;

        private String username;

        private String firstName;

        private String lastName;

        private String password;

        private Role role;

        private SocialMediaService socialSignInProvider;

        private Set<GrantedAuthority> authorities;

        public Builder() {
            this.authorities = new HashSet<>();
        }

        public Builder firstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder id(Long id) {
            this.id = id;
            return this;
        }

        public Builder lastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public Builder password(String password) {
            if (password == null) {
                password = "SocialUser";
            }

            this.password = password;
            return this;
        }

        public Builder role(Role role) {
            this.role = role;

            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.toString());
            this.authorities.add(authority);

            return this;
        }

        public Builder socialSignInProvider(SocialMediaService socialSignInProvider) {
            this.socialSignInProvider = socialSignInProvider;
            return this;
        }

        public Builder username(String username) {
            this.username = username;
            return this;
        }

        public ExampleUserDetails build() {
            ExampleUserDetails user = new ExampleUserDetails(username, password, authorities);

            user.id = id;
            user.firstName = firstName;
            user.lastName = lastName;
            user.role = role;
            user.socialSignInProvider = socialSignInProvider;

            return user;
        }
    }
}

Die Rolle ist eine einfache Aufzählung, die die "legalen" Benutzerrollen unserer Beispielanwendung angibt. Sein Quellcode sieht wie folgt aus:

public enum Role {
    ROLE_USER
}

Der SocialMediaService ist eine Aufzählung, die den SaaS-API-Anbieter identifiziert, der verwendet wurde, als der Benutzer ein Benutzerkonto für unsere Beispielanwendung erstellte. Sein Quellcode sieht wie folgt aus:

public enum SocialMediaService {
    FACEBOOK,
    TWITTER
}

Implementierung der UserDetailsService-Schnittstelle

Wir können unsere eigene Implementierung des UserDetailsService erstellen Schnittstelle, indem Sie diesen Schritten folgen:

  1. Erstellen Sie eine Klasse, die den UserDetailsService implementiert Schnittstelle.
  2. Fügen Sie ein UserRepository hinzu Feld zur erstellten Klasse.
  3. Erstellen Sie einen Konstruktor, der ein UserRepository übernimmt als Konstruktorargument und kommentieren Sie den Konstruktor mit @Autowired Anmerkung.
  4. Implementieren Sie loadUserByUsername(String username) Methode des UserDetailsService Schnittstelle. Die Implementierung dieser Methode besteht aus folgenden Schritten:
    1. Rufen Sie den Benutzer ab, indem Sie findByEmail() aufrufen Methode des UserRepository Schnittstelle. Diese Methode gibt den Benutzer zurück, dessen E-Mail mit dem als Methodenparameter angegebenen Benutzernamen übereinstimmt.
    2. Wenn der Benutzer nicht gefunden wird, lösen Sie eine neue UsernameNotFoundException aus .
    3. Erstellen Sie ein neues ExampleUserDetails Objekt.
    4. Gib das erstellte Objekt zurück.

Der Quellcode des RepositoryUserDetailsService Klasse sieht wie folgt aus:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class RepositoryUserDetailsService implements UserDetailsService {

    private UserRepository repository;

    @Autowired
    public RepositoryUserDetailsService(UserRepository repository) {
        this.repository = repository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = repository.findByEmail(username);

        if (user == null) {
            throw new UsernameNotFoundException("No user found with username: " + username);
        }

        ExampleUserDetails principal = ExampleUserDetails.getBuilder()
                .firstName(user.getFirstName())
                .id(user.getId())
                .lastName(user.getLastName())
                .password(user.getPassword())
                .role(user.getRole())
                .socialSignInProvider(user.getSignInProvider())
                .username(user.getEmail())
                .build();

        return principal;
    }
}

Das UserRepository ist ein einfaches Spring Data JPA-Repository und sein Quellcode sieht wie folgt aus:

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {

    public User findByEmail(String email);
}

Der Benutzer ist die einzige Entität unserer Beispielanwendung und enthält die Informationen eines Benutzers, der ein Benutzerkonto für unsere Beispielanwendung erstellt hat. Der relevante Teil des Quellcodes sieht wie folgt aus:

import javax.persistence.*;

@Entity
@Table(name = "user_accounts")
public class User extends BaseEntity<Long> {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "email", length = 100, nullable = false, unique = true)
    private String email;

    @Column(name = "first_name", length = 100,nullable = false)
    private String firstName;

    @Column(name = "last_name", length = 100, nullable = false)
    private String lastName;

    @Column(name = "password", length = 255)
    private String password;

    @Enumerated(EnumType.STRING)
    @Column(name = "role", length = 20, nullable = false)
    private Role role;

    @Enumerated(EnumType.STRING)
    @Column(name = "sign_in_provider", length = 20)
    private SocialMediaService signInProvider;

    public User() {

    }

	//Getters and other methods are omitted for the sake of clarity.
}

Implementieren der SocialUserDetailsService-Schnittstelle

Wir können den SocialUserDetailsService implementieren Schnittstelle, indem Sie diesen Schritten folgen:

  1. Erstellen Sie eine Klasse, die den SocialUserDetailsService implementiert .
  2. Fügen Sie einen UserDetailsService hinzu Feld zur erstellten Klasse.
  3. Erstellen Sie einen Konstruktor, der einen UserDetailsService übernimmt Objekt als Konstruktorparameter und kommentieren Sie den Konstruktor mit @Autowired Anmerkung.
  4. Implementieren Sie loadUserByUserId(String userId) Methode des SocialUserDetailsInterface .
  5. Erhalten Sie die korrekten Benutzerdetails Objekt durch Aufrufen von loadUserByUsername() -Methode und übergeben Sie die Benutzer-ID als Methodenparameter. Dies ist möglich, da unsere Anwendung den Benutzernamen des Benutzers als Benutzer-ID verwendet.
  6. Wandle das zurückgegebene Objekt in SocialUserDetails um Objekt und gib es zurück.

Der Quellcode des SimpleSocialUserDetailsService Klasse sieht wie folgt aus:

import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.social.security.SocialUser;
import org.springframework.social.security.SocialUserDetails;
import org.springframework.social.security.SocialUserDetailsService;


public class SimpleSocialUserDetailsService implements SocialUserDetailsService {

    private UserDetailsService userDetailsService;

    public SimpleSocialUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException, DataAccessException {
        UserDetails userDetails = userDetailsService.loadUserByUsername(userId);
        return (SocialUserDetails) userDetails;
    }
}

Das ist alles. Wir können jetzt den Anwendungskontext unserer Anwendung konfigurieren. Lassen Sie uns herausfinden, wie wir das tun können.

Anwendungskontext konfigurieren

Dieser Abschnitt beschreibt, wie wir den Anwendungskontext unserer Beispielanwendung mithilfe der Java-Konfiguration konfigurieren können. Die Anwendungskontextkonfiguration wurde gemäß den folgenden Richtlinien in mehrere Konfigurationsklassen unterteilt:

  1. Jede Konfigurationsklasse enthält eine Konfiguration, die einem bestimmten Teil unserer Beispielanwendung zugeordnet ist. Dies macht es einfach, die relevante Konfiguration herauszufinden, wenn wir einige Monate (oder Jahre) nachdem wir die ursprüngliche Konfiguration erstellt haben, etwas überprüfen oder ändern müssen.
  2. Die Konfiguration wurde so aufgeteilt, dass es einfach ist, Komponententests für die Webschicht mit Spring MVC Test zu schreiben. Wir werden im dritten Teil dieses Tutorials mehr darüber sprechen, wo wir Komponententests für die Webschicht unserer Anwendung schreiben werden.
  3. Die Konfiguration erleichtert das Entfernen von Abhängigkeiten zu externen Ressourcen, wenn wir Integrationstests für unsere Anwendung schreiben. Wir werden im vierten Teil dieses Tutorials mehr darüber sprechen, der beschreibt, wie wir Integrationstests für unsere Anwendung schreiben können.

Beginnen wir mit der Konfiguration der Persistenzschicht unserer Anwendung.

Konfigurieren der Persistenzschicht

Die Persistenzschicht unserer Anwendung speichert die Benutzerkontoinformationen und bietet eine Möglichkeit, auf diese Informationen zuzugreifen. Dies ist aus zwei Gründen wichtig:

  • Wir können eine Möglichkeit bieten, sich mit Benutzername und Passwort anzumelden.
  • Wir können anwendungsspezifische Informationen speichern und diese Informationen mit dem Benutzer verknüpfen, der die soziale Anmeldung verwendet.

Lassen Sie uns herausfinden, wie wir es konfigurieren können, indem wir beide Java-Konfigurationsklassen verwenden.

Wir können unsere Persistenzschicht konfigurieren, indem wir diesen Schritten folgen:

  1. Erstellen Sie die Konfigurationsklasse und kommentieren Sie die erstellte Klasse mit @Configuration Anmerkung.
  2. Kommentieren Sie die Klasse mit @EnableJpaRepositories Anmerkung und legen Sie das Basispaket unserer Spring Data JPA-Repositories fest.
  3. Aktivieren Sie die Spring-Transaktionsverwaltung, indem Sie die Konfigurationsklasse mit @EnableTransactionManagement kommentieren Anmerkung.
  4. Fügen Sie eine Umgebung hinzu Feld zur Klasse und kommentieren Sie das Feld mit @Autowired Anmerkung. Wir müssen die Eigenschaftendatei nicht mithilfe von @PropertySource konfigurieren Anmerkung, da sie bereits in der Konfigurationsklasse "übergeordneter" Anwendungskontext konfiguriert ist.
  5. Konfigurieren Sie die Datenquellen-Bean. Diese Bean stellt Datenbankverbindungen zum Entitätsmanager bereit, hat aber auch einen anderen Zweck. Es wird von Spring Social verwendet, wenn es Verbindungen zur Datenbank aufrechterhält und sie aus der Datenbank lädt.
  6. Konfigurieren Sie die Transaktionsmanager-Bean.
  7. Factory-Bean des Entitätsmanagers konfigurieren.

Der Quellcode des PersistenceContext Klasse sieht wie folgt aus:

import com.jolbox.bonecp.BoneCPDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableJpaRepositories(basePackages = {
        "net.petrikainulainen.spring.social.signinmvc.user.repository"
})
@EnableTransactionManagement
public class PersistenceContext {

    @Resource
    private Environment env;

    @Bean
    public DataSource dataSource() {
        BoneCPDataSource dataSource = new BoneCPDataSource();

        dataSource.setDriverClass(env.getRequiredProperty("db.driver"));
        dataSource.setJdbcUrl(env.getRequiredProperty("db.url"));
        dataSource.setUsername(env.getRequiredProperty("db.username"));
        dataSource.setPassword(env.getRequiredProperty("db.password"));

        return dataSource;
    }

    @Bean
    public JpaTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
        return transactionManager;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        entityManagerFactoryBean.setPackagesToScan({
	            "net.petrikainulainen.spring.social.signinmvc.common.model",
	            "net.petrikainulainen.spring.social.signinmvc.user.model"
	    });

        Properties jpaProperties = new Properties();
        jpaProperties.put("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
        jpaProperties.put("hibernate.format_sql", env.getRequiredProperty("hibernate.format_sql"));
        jpaProperties.put("hibernate.hbm2ddl.auto", env.getRequiredProperty("hibernate.hbm2ddl.auto"));
        jpaProperties.put("hibernate.ejb.naming_strategy", env.getRequiredProperty("hibernate.ejb.naming_strategy"));
        jpaProperties.put("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));

        entityManagerFactoryBean.setJpaProperties(jpaProperties);

        return entityManagerFactoryBean;
    }
}

Lassen Sie uns weitermachen und herausfinden, wie wir die Sicherheitskonfiguration für unsere Anwendung erstellen können.

Spring Security konfigurieren

Spring Security bietet Authentifizierungsmechanismen für Benutzer, die entweder die Formularanmeldung oder die soziale Anmeldung verwenden, und ist auch für die Autorisierung verantwortlich.

Wir können Spring Security konfigurieren, indem wir diesen Schritten folgen:

  1. Erstellen Sie die Konfigurationsklasse und kommentieren Sie die erstellte Klasse mit @Configuration Anmerkung.
  2. Kommentieren Sie die Klasse mit @EnableWebSecurity Anmerkung. Dadurch ist es möglich, Spring Security durch Implementierung des WebSecurityConfigurer zu konfigurieren Schnittstelle.
  3. Stellen Sie sicher, dass unsere Konfigurationsklasse den WebSecurityConfigurerAdapter erweitert -Klasse, die eine Basisklasse zum Erstellen von WebSecurityConfigurer ist Instanzen. Nachdem wir dies getan haben, können wir die Sicherheitskonfiguration anpassen, indem wir Methoden überschreiben.
  4. Fügen Sie ein UserRepository hinzu Feld zur Konfiguration und kommentieren Sie das Feld mit @Autowired Anmerkung.
  5. Überschreiben Sie configure(WebSecurity web) Methode des WebSecurityConfigurerAdapter Klasse. Stellen Sie sicher, dass Spring Security Anfragen an statische Ressourcen wie CSS- und Javascript-Dateien ignoriert.
  6. Überschreiben Sie die configure(HttpSecurity http) Methode des WebSecurityConfigurerAdapter Klasse und implementieren Sie sie, indem Sie die folgenden Schritte ausführen:
    1. Konfigurieren Sie die Formularanmeldung, indem Sie diesen Schritten folgen:
      1. Setzen Sie die URL der Anmeldeseite auf '/login'.
      2. Setzen Sie die URL, die Anmeldeformularübermittlungen verarbeitet, auf „/login/authenticate“.
      3. Setzen Sie die Anmeldefehler-URL auf '/login?error=bad_credentials'.
    2. Konfigurieren Sie die Abmeldefunktion, indem Sie diesen Schritten folgen:
      1. Stellen Sie sicher, dass ein Cookie namens JSESSIONID wird nach Abmeldung gelöscht.
      2. Setzen Sie die Abmelde-URL auf '/logout'.
      3. Setzen Sie die erfolgreiche Abmelde-URL auf „/login“.
    3. URL-basierte Autorisierung konfigurieren. Der Hauptpunkt dieser Phase besteht darin, sicherzustellen, dass anonyme Benutzer auf alle URLs zugreifen können, die sich auf den Anmelde-/Registrierungsprozess beziehen, und den Rest unserer Anwendung vor anonymen Benutzern zu schützen.
    4. Fügen Sie den SocialAuthenticationFilter hinzu zur Filterkette von Spring Security. Wir können dies tun, indem wir einen neuen SpringSocialConfigurer erstellen -Objekt und stellen Sie sicher, dass dieses Objekt verwendet wird, wenn Spring Security konfiguriert wird.
  7. Konfigurieren Sie den PasswordEncoder Bean, die verwendet wird, um das Passwort des Benutzers zu hashen (wenn der Benutzer Formularregistrierung und Anmeldung verwendet). Wir können dies tun, indem wir einen neuen BCryptPasswordEncoder erstellen Objekt und Rückgabe des erstellten Objekts.
  8. Konfigurieren Sie den UserDetailsService Bohne. Wir können dies tun, indem wir einen neuen RepositoryUserDetailsService erstellen -Objekt und das Übergeben des UserRepository als Konstruktorargument.
  9. Überschreiben Sie configure(AuthenticationManagerBuilder auth) Methode des WebSecurityConfigurerAdapter Klasse. Wir verwenden diese Methode zum Konfigurieren von Authentifizierungsanforderungen, wenn der Benutzer die Formularanmeldung verwendet. Implementieren Sie diese Methode, indem Sie die folgenden Schritte ausführen:
    1. Übergeben Sie den UserDetailsService Bean zum AuthenticationManagerBuilder Objekt als Methodenparameter angegeben.
    2. Übergeben Sie den PasswordEncoder Bean zum AuthenticationManagerBuilder Objekt als Methodenparameter angegeben.
  10. Konfigurieren Sie den SocialUserDetailsService Bohne. Wir können dies tun, indem wir einen neuen SimpleSocialUserDetailsService erstellen -Objekt und Übergeben des UserDetailsService Bean als Konstruktorargument. Diese Bean lädt die benutzerspezifischen Daten, wenn die soziale Anmeldung verwendet wird.

Der Quellcode unserer Anwendungskontext-Konfigurationsklasse sieht wie folgt aus:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.social.security.SocialUserDetailsService;
import org.springframework.social.security.SpringSocialConfigurer;

@Configuration
@EnableWebSecurity
public class SecurityContext extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepository userRepository;

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
                //Spring Security ignores request to static resources such as CSS or JS files.
                .ignoring()
                    .antMatchers("/static/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //Configures form login
                .formLogin()
                    .loginPage("/login")
                    .loginProcessingUrl("/login/authenticate")
                    .failureUrl("/login?error=bad_credentials")
                //Configures the logout function
                .and()
                    .logout()
                        .deleteCookies("JSESSIONID")
                        .logoutUrl("/logout")
                        .logoutSuccessUrl("/login")
                //Configures url based authorization
                .and()
                    .authorizeRequests()
                        //Anyone can access the urls
                        .antMatchers(
                                "/auth/**",
                                "/login",
                                "/signup/**",
                                "/user/register/**"
                        ).permitAll()
                        //The rest of the our application is protected.
                        .antMatchers("/**").hasRole("USER")
                //Adds the SocialAuthenticationFilter to Spring Security's filter chain.
                .and()
                    .apply(new SpringSocialConfigurer());
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService())
                .passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(10);
    }

    @Bean
    public SocialUserDetailsService socialUserDetailsService() {
        return new SimpleSocialUserDetailsService(userDetailsService());
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new RepositoryUserDetailsService(userRepository);
    }
}

Lassen Sie uns weitermachen und herausfinden, wie wir Spring Social konfigurieren können.

Spring Social konfigurieren

Spring Social bietet Integrationen mit SaaS-API-Anbietern wie Facebook und Twitter. Wir können Spring Social konfigurieren, indem wir diesen Schritten folgen:

  1. Erstellen Sie die Anwendungskontext-Konfigurationsklasse, die den SocialConfigurer implementiert -Schnittstelle und kommentieren Sie die erstellte Klasse mit @Configuration Anmerkung. Die SocialConfigurer-Schnittstelle deklariert Callback-Methoden, die zur Konfiguration von Spring Social verwendet werden können.
  2. Kommentieren Sie die Klasse mit @EnableSocial Anmerkung. Dadurch wird Spring Social aktiviert und die SocialConfiguration importiert Konfigurationsklasse.
  3. Fügen Sie eine Datenquelle hinzu Feld zur Konfigurationsklasse und kommentieren Sie das Feld mit @Autowired Anmerkung.
  4. Fügen Sie die addConnectionFactories() hinzu Methode des SocialConfigurer Schnittstelle zur erstellten Konfigurationsklasse. Diese Methode nimmt zwei Methodenparameter entgegen, die im Folgenden beschrieben werden:
    1. Der erste Parameter ist ein ConnectionFactoryConfigurer Objekt, das zum Registrieren von Verbindungsfabriken verwendet werden kann.
    2. Der zweite Parameter ist eine Umgebung -Objekt, das die Umgebung darstellt, in der unsere Beispielanwendung ausgeführt wird.
  5. Implementieren Sie die addConnectionFactories() Methode, indem Sie die folgenden Schritte ausführen:
    1. Erstellen Sie eine neue TwitterConnectionFactory Objekt und übergeben Sie den Verbraucherschlüssel und das Verbrauchergeheimnis als Konstruktorargumente.
    2. Registrieren Sie die erstellte TwitterConnectionFactory Objekt durch Aufrufen von addConnectionFactory() Methode des ConnectionFactoryConfigurer Schnittstelle. Übergeben Sie die erstellte TwitterConnectionFactory Objekt als Methodenparameter.
    3. Erstellen Sie eine neue FacebookConnectionFactory -Objekt und übergeben Sie die Anwendungs-ID und das Anwendungsgeheimnis als Konstruktorargumente.
    4. Registrieren Sie die erstellte FacebookConnectionFactory -Objekt durch Aufrufen der addConnectionFactory Methode des ConnectionFactoryConfigurer Schnittstelle. Übergeben Sie die erstellte FacebookConnectionFactory Objekt als Methodenparameter.
  6. Fügen Sie getUserIdSource() hinzu Methode des SocialConfigurer Schnittstelle zur erstellten Klasse. Die UserIdSource Das von dieser Methode zurückgegebene Objekt ist für die Bestimmung der korrekten Konto-ID des Benutzers verantwortlich. Da unsere Beispielanwendung den Benutzernamen des Benutzers als Konto-ID verwendet, müssen wir diese Methode implementieren, indem wir eine neue AuthenticationNameUserIdSource zurückgeben Objekt.
  7. Fügen Sie das getUsersConnectionRepository() hinzu Methode des SocialConfigurer Schnittstelle zur erstellten Klasse. Diese Methode akzeptiert einen ConnectionFactoryLocator Objekt als Methodenparameter und gibt ein UsersConnectionRepository zurück Objekt.
  8. Implementieren Sie das getUsersConnectionRepository() Methode, indem Sie die folgenden Schritte ausführen:
    1. Erstellen Sie ein neues JdbcUsersConnectionRepository Objekt und übergeben Sie die folgenden Objekte als Konstruktorargumente:
      1. Das erste Argument ist eine Datenquelle Objekt. Wir übergeben den Wert der dataSource Feld als erster Methodenparameter.
      2. Das zweite Argument ist ein ConnectionFactoryLocator Objekt. Wir übergeben den Wert des connectionFactoryLocator Methodenparameter als zweiten Methodenparameter.
      3. Der dritte Parameter ist ein TextEncryptor -Objekt, das die Autorisierungsdetails der zwischen einem SaaS-API-Anbieter und unserer Anwendung hergestellten Verbindung verschlüsselt. Wir erstellen dieses Objekt, indem wir noOpText() aufrufen Methode des Encryptors Klasse. Das bedeutet, dass unsere Beispielanwendung diese Details als Klartext speichert. Dies ist während der Entwicklungsphase praktisch, aber wir sollten es nicht in der Produktion verwenden .
    2. Gib das erstellte Objekt zurück.
  9. Konfigurieren Sie den ConnectController Bohne. Die Methode, die diese Bean konfiguriert, hat zwei Parameter. Der erste Parameter ist der ConnectionFactoryLocator Bohne. Der zweite Parameter ist das verwendete ConnectionRepository Bohne. Übergeben Sie diese Parameter als Konstruktorargumente, wenn Sie einen neuen ConnectController erstellen Objekt.

Der Quellcode unserer Konfigurationsklasse sieht wie folgt aus:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.social.UserIdSource;
import org.springframework.social.config.annotation.ConnectionFactoryConfigurer;
import org.springframework.social.config.annotation.EnableSocial;
import org.springframework.social.config.annotation.SocialConfigurer;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.ConnectionRepository;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository;
import org.springframework.social.connect.web.ConnectController;
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
import org.springframework.social.security.AuthenticationNameUserIdSource;
import org.springframework.social.twitter.connect.TwitterConnectionFactory;

import javax.sql.DataSource;

@Configuration
@EnableSocial
public class SocialContext implements SocialConfigurer {

    @Autowired
    private DataSource dataSource;

    @Override
    public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {
        cfConfig.addConnectionFactory(new TwitterConnectionFactory(
                env.getProperty("twitter.consumer.key"),
                env.getProperty("twitter.consumer.secret")
        ));
        cfConfig.addConnectionFactory(new FacebookConnectionFactory(
                env.getProperty("facebook.app.id"),
                env.getProperty("facebook.app.secret")
        ));
    }

    @Override
    public UserIdSource getUserIdSource() {
        return new AuthenticationNameUserIdSource();
    }

    @Override
    public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        return new JdbcUsersConnectionRepository(
                dataSource,
                connectionFactoryLocator,
                Encryptors.noOpText()
        );
    }

    @Bean
    public ConnectController connectController(ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) {
        return new ConnectController(connectionFactoryLocator, connectionRepository);
    }
}

Unser nächster Schritt ist die Konfiguration der Webschicht unserer Anwendung. Machen wir uns an die Arbeit.

Konfigurieren der Webschicht

Wir können die Webschicht unserer Anwendung konfigurieren, indem wir diesen Schritten folgen:

  1. Erstellen Sie die Konfigurationsklasse, indem Sie diesen Schritten folgen:
    1. Erweitern Sie den WebMvcConfigurerAdapter Klasse.
    2. Kommentieren Sie die erstellte Klasse mit @Configuration Anmerkung.
  2. Stellen Sie sicher, dass alle Controller-Klassen gefunden werden, indem Sie die Klasse mit @ComponentScan kommentieren Anmerkung und Einstellung der Basispakete unserer Controller.
  3. Aktivieren Sie das annotationsgesteuerte Web-MVC, indem Sie die Klasse mit @EnableWebMvc annotieren Anmerkung.
  4. Stellen Sie sicher, dass statische Ressourcen vom Standard-Servlet des Containers bereitgestellt werden.
    1. Konfigurieren Sie die statischen Ressourcen, indem Sie addResourceHandlers() überschreiben -Methode des WebMvcConfigurerAdapter Klasse.
    2. Stellen Sie sicher, dass Anforderungen an statische Ressourcen an das Standard-Servlet des Containers weitergeleitet werden. Dies geschieht durch Überschreiben von configureDefaultServletHandling() -Methode des WebMvcConfigurerAdapter Klasse.
  5. Konfigurieren Sie die Ausnahme-Resolver-Bean.
  6. Konfigurieren Sie die ViewResolver-Bean.

Der Quellcode des WebAppContext Klasse sieht wie folgt aus:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import java.util.Properties;

@Configuration
@ComponentScan(basePackages = {
        "net.petrikainulainen.spring.social.signinmvc.common.controller",
        "net.petrikainulainen.spring.social.signinmvc.security.controller",
        "net.petrikainulainen.spring.social.signinmvc.user.controller"
})
@EnableWebMvc
public class WebAppContext extends WebMvcConfigurerAdapter {

	@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("/static/");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public SimpleMappingExceptionResolver exceptionResolver() {
        SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();

        Properties exceptionMappings = new Properties();

        exceptionMappings.put("java.lang.Exception", "error/error");
        exceptionMappings.put("java.lang.RuntimeException", "error/error");

        exceptionResolver.setExceptionMappings(exceptionMappings);

        Properties statusCodes = new Properties();

        statusCodes.put("error/404", "404");
        statusCodes.put("error/error", "500");

        exceptionResolver.setStatusCodes(statusCodes);

        return exceptionResolver;
    }

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");

        return viewResolver;
    }
}

Lassen Sie uns herausfinden, wie wir dies alles miteinander verbinden und eine "übergeordnete" Anwendungskontext-Konfigurationsklasse für unsere Anwendung erstellen können.

Alles zusammenbinden

Die letzte Anwendungskontext-Konfigurationsklasse hat drei Verantwortlichkeiten:

  1. Es konfiguriert allgemeine Komponenten, die in unserer Beispielanwendung verwendet werden.
  2. Es stellt sicher, dass die Dienstklassen unserer Anwendung während des Classpath-Scans gefunden werden.
  3. Es ist die Root-Anwendungskontext-Konfigurationsklasse unserer Anwendung.

Wir können diese Konfigurationsklasse erstellen, indem wir diesen Schritten folgen:

  1. Erstellen Sie die Konfigurationsklasse und kommentieren Sie die erstellte Klasse mit @Configuration Anmerkung.
  2. Stellen Sie sicher, dass unsere Dienstklassen während des Komponenten-Scans gefunden werden, indem Sie die Klasse mit @ComponentScan kommentieren Anmerkung und Festlegung des Basispakets unserer Dienstleistungen.
  3. Importieren Sie die anderen Anwendungskontext-Konfigurationsklassen, indem Sie die Klasse mit @Import kommentieren Anmerkung.
  4. Kommentieren Sie die Klasse mit @PropertySource -Anmerkung und konfigurieren Sie sie so, dass sie nach einer Eigenschaftendatei namens application.properties sucht aus dem Klassenpfad. Dadurch wird sichergestellt, dass auf die Konfigurationseigenschaften in den importierten Anwendungskontext-Konfigurationsklassen zugegriffen werden kann.
  5. Konfigurieren Sie die MessageSource Bohne.
  6. Konfigurieren Sie den PropertySourcesPlaceholderConfigurer Bohne.

Der Quellcode der ExampleApplicationContext Klasse sieht wie folgt aus:

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.context.support.ResourceBundleMessageSource;

@Configuration
@ComponentScan(basePackages = {
        "net.petrikainulainen.spring.social.signinmvc.user.service"
})
@Import({WebAppContext.class, PersistenceContext.class, SecurityContext.class, SocialContext.class})
@PropertySource("classpath:application.properties")
public class ExampleApplicationContext {

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();

        messageSource.setBasename("i18n/messages");
        messageSource.setUseCodeAsDefaultMessage(true);

        return messageSource;
    }

    @Bean
    public PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

Wir haben nun den Anwendungskontext unserer Beispielanwendung konfiguriert. Allerdings müssen wir unsere Webanwendung noch konfigurieren. Sehen wir uns an, wie wir dies mithilfe der Java-Konfiguration erreichen können.

Konfigurieren der Webanwendung

Unser letzter Schritt ist die Konfiguration unserer Beispielanwendung. Wir können dies ohne web.xml tun solange unsere Anwendung in einem Servlet 3.0-kompatiblen Container bereitgestellt wird.

Wir können die Webanwendung konfigurieren, indem wir diesen Schritten folgen:

  1. Erstellen Sie eine Klasse, die den WebApplicationInitializer implementiert Schnittstelle.
  2. Konfigurieren Sie unsere Anwendung, indem Sie onStartup() überschreiben Methode des WebApplicationInitializer Schnittstelle. Wir können diese Methode implementieren, indem wir die folgenden Schritte ausführen:
    1. Erstellen Sie den Stammkontext der Anwendung und registrieren Sie den ExampleApplicationContext Klasse in den erstellten Stammkontext.
    2. Konfigurieren Sie das Dispatcher-Servlet.
    3. Zeichenkodierungsfilter konfigurieren.
    4. Konfigurieren Sie die Spring Security-Filterkette.
    5. Sitemesh konfigurieren.
    6. Fügen Sie den Context Loader Listener zum Servlet-Kontext hinzu.

Der Quellcode der ExampleApplicationConfig Klasse sieht wie folgt aus:

import org.sitemesh.config.ConfigurableSiteMeshFilter;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.*;
import java.util.EnumSet;

public class ExampleApplicationConfig implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ExampleApplicationContext.class);

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);

        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);

        FilterRegistration.Dynamic characterEncoding = servletContext.addFilter("characterEncoding", characterEncodingFilter);
        characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");

        FilterRegistration.Dynamic security = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
        security.addMappingForUrlPatterns(dispatcherTypes, true, "/*");

        FilterRegistration.Dynamic sitemesh = servletContext.addFilter("sitemesh", new ConfigurableSiteMeshFilter());
        sitemesh.addMappingForUrlPatterns(dispatcherTypes, true, "*.jsp");

        servletContext.addListener(new ContextLoaderListener(rootContext));
    }
}

Was kommt als Nächstes?

Wir haben unsere Beispielanwendung nun erfolgreich mithilfe der Java-Konfiguration konfiguriert. Dieses Tutorial hat uns zwei Dinge beigebracht:

  • Wir haben gelernt, wie wir die von Spring Security und Spring Social geforderten Komponenten implementieren können.
  • Wir haben gelernt, Spring Security und Spring Social mithilfe der Java-Konfiguration zu integrieren.

Der nächste Teil dieses Tutorials beschreibt, wie wir Registrierungs- und Anmeldefunktionen zu unserer Beispielanwendung hinzufügen können.

Die Beispielanwendung dieses Blogbeitrags ist wie immer auf Github verfügbar.


Java-Tag