日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

将社交登录添加到Spring MVC Web应用程序:配置

發(fā)布時(shí)間:2023/12/3 javascript 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 将社交登录添加到Spring MVC Web应用程序:配置 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

過去,用戶使用用戶名和密碼組合登錄。 盡管如今有些人仍然偏愛傳統(tǒng)方式,但越來越多的用戶希望使用其社交媒體帳戶登錄。

這就是使Spring Social(及其子項(xiàng)目)成為Spring項(xiàng)目組合有用的補(bǔ)充的原因。 但是,將Spring Social與Spring Security集成起來有點(diǎn)麻煩。

Spring Social 1.1.0改變了這一切。 它提供了與Spring Security的無縫集成,并且Spring Security的Java配置支持使配置就像在公園里散步一樣。

您不必相信我的話。 繼續(xù)閱讀,您將學(xué)到如何做到這一點(diǎn)。

我們解決方案的要求如下:

  • 必須可以使用常規(guī)注冊(cè)表單創(chuàng)建用戶帳戶。
  • 必須有可能通過使用社交登錄來創(chuàng)建用戶帳戶。
  • 必須可以使用用戶名和密碼登錄。
  • 必須可以使用SaaS API提供程序進(jìn)行登錄。
  • 該應(yīng)用程序必須支持Facebook和Twitter。
  • 應(yīng)用程序必須使用“常規(guī)” Spring MVC控制器(無REST)。

讓我們先看一下本教程的先決條件。

先決條件

本教程假定您已經(jīng)創(chuàng)建了示例應(yīng)用程序使用的Facebook和Twitter應(yīng)用程序。 您可以通過以下鏈接創(chuàng)建這些應(yīng)用程序:

  • Facebook開發(fā)人員
  • Twitter開發(fā)人員

如果您不知道該怎么做,可以查看以下鏈接:

  • Facebook開發(fā)人員–創(chuàng)建應(yīng)用程序詳細(xì)信息頁面 (當(dāng)系統(tǒng)詢問您的應(yīng)用程序如何與FB集成時(shí),選擇“使用Facebook登錄名的網(wǎng)站”)。
  • 如何通過8個(gè)簡(jiǎn)單步驟創(chuàng)建Twitter應(yīng)用程序 (啟用“允許該應(yīng)用程序用于通過Twitter登錄”復(fù)選框)。

讓我們繼續(xù)前進(jìn),了解如何使用Maven獲得所需的依賴關(guān)系。

使用Maven獲取所需的依賴關(guān)系

我們要做的第一件事是使用Maven獲得所需的依賴關(guān)系。 為此,我們可以在POM文件中聲明以下依賴關(guān)系:

  • Spring Security(版本3.2.0.RC1)。
    • 核心模塊包含核心身份驗(yàn)證和訪問控制組件。
  • Apache HttpClient(版本4.2.5)。 Apache HttpClient是Spring Social的可選依賴項(xiàng)(但建議使用)。 如果存在,Spring Social會(huì)將其用作HTTP客戶端。 否則,Spring social將使用標(biāo)準(zhǔn)的Java SE組件。
  • Spring社交(版本1.1.0.BUILD-SNAPSHOT)。
    • 核心模塊包含連接框架,并為OAuth客戶端提供支持。
  • Spring Social Facebook(版本1.1.0.BUILD-SNAPSHOT)是Spring Social的擴(kuò)展,它提供Facebook集成。
  • Spring Social Twitter(版本1.1.0.BUILD-SNAPSHOT)是對(duì)Social Social的擴(kuò)展,它提供了Twitter集成。

pom.xml文件的相關(guān)部分如下所示:

<!-- Spring Security --> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId><version>3.2.0.RC1</version> </dependency> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>3.2.0.RC1</version> </dependency> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-taglibs</artifactId><version>3.2.0.RC1</version> </dependency> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>3.2.0.RC1</version> </dependency><!-- Use Apache HttpClient as HTTP Client --> <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.2.5</version> </dependency><!-- Spring Social --> <dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-core</artifactId><version>1.1.0.BUILD-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.social</groupId><artifactId>spring-social-security</artifactId><version>1.1.0.BUILD-SNAPSHOT</version> </dependency> <dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-web</artifactId><version>1.1.0.BUILD-SNAPSHOT</version> </dependency><!-- Spring Social Facebook --> <dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-facebook</artifactId><version>1.1.0.BUILD-SNAPSHOT</version> </dependency><!-- Spring Social Twitter --> <dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-twitter</artifactId><version>1.1.0.BUILD-SNAPSHOT</version> </dependency>

注意 :我們的應(yīng)用程序還具有其他依賴項(xiàng)。 例如,它使用Spring Framework 3.2.4.RELEASE,Spring Data JPA 1.3.4和Hibernate 4.2.4.Final。 為了清楚起見,這些依賴項(xiàng)從依賴項(xiàng)列表中省略。 您可以從Github獲取依賴項(xiàng)的完整列表 。

您可能還想閱讀以下文檔,這些文檔為您提供了有關(guān)此博客文章(Spring Security和Spring Social)中討論的框架的依賴性的更多信息:

  • Spring Security參考手冊(cè):1.4獲取Spring Security
  • Spring社會(huì)參考手冊(cè):1.3如何獲得
  • Spring Social Facebook參考手冊(cè):1.2如何獲取
  • Spring Social Twitter參考手冊(cè):1.2如何獲取

接下來,我們必須為應(yīng)用程序的配置屬性創(chuàng)建一個(gè)屬性文件。 讓我們找出這是如何完成的。

創(chuàng)建屬性文件

我們可以按照以下步驟創(chuàng)建屬性文件:

  • 創(chuàng)建一個(gè)名為application.properties的文件,并確保從類路徑中找到它。
  • 配置數(shù)據(jù)庫連接。
  • 配置休眠。
  • 將Facebook應(yīng)用程序ID和應(yīng)用程序密鑰添加到屬性文件。
  • 將Twitter使用者密鑰和使用者密鑰添加到屬性文件中。
  • application.properties文件的內(nèi)容如下所示:

    #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

    在配置應(yīng)用程序之前,我們必須創(chuàng)建一些通用組件。 讓我們找出這些組件是什么,以及如何創(chuàng)建它們。

    創(chuàng)建通用組件

    我們必須創(chuàng)建在身份驗(yàn)證過程中使用的三個(gè)組件。 這些組件是:

    • 我們創(chuàng)建了一個(gè)類,其中包含經(jīng)過身份驗(yàn)證的用戶的用戶詳細(xì)信息。
    • 我們必須創(chuàng)建一個(gè)實(shí)現(xiàn)UserDetailsS??ervice接口的類。 當(dāng)用戶使用表單登錄時(shí),此類用于加載用戶信息。
    • 我們必須創(chuàng)建一個(gè)實(shí)現(xiàn)SocialUserDetailsS??ervice接口的類。 當(dāng)用戶使用社交登錄時(shí),該類用于加載用戶信息。

    讓我們繼續(xù)前進(jìn),找出如何實(shí)現(xiàn)這些類。

    創(chuàng)建用戶詳細(xì)信息類

    在創(chuàng)建包含已認(rèn)證用戶的用戶詳細(xì)信息的類時(shí),我們必須考慮以下要求:

    • 存儲(chǔ)使用表單登錄的用戶的用戶詳細(xì)信息的類必須實(shí)現(xiàn)UserDetails接口。
    • 存儲(chǔ)使用社交登錄的用戶的用戶詳細(xì)信息的類必須實(shí)現(xiàn)SocialUserDetails接口。

    Spring Social具有滿足這兩個(gè)要求的SocialUser類。 但是,通常我們希望將特定于應(yīng)用程序的信息添加到我們的用戶詳細(xì)信息類中。

    我們可以按照以下步驟進(jìn)行操作:

  • 創(chuàng)建用戶詳細(xì)信息類。
  • 擴(kuò)展SocialUser類。
  • 將應(yīng)用程序特定的字段添加到創(chuàng)建的類。 我們的示例應(yīng)用程序的特定于應(yīng)用程序的字段是: id , firstName , lastName , role和socialSignInProvider 。
  • 創(chuàng)建一個(gè)構(gòu)造函數(shù),該構(gòu)造函數(shù)將用戶名,密碼和授予的權(quán)限的集合作為參數(shù)。 將這些參數(shù)傳遞給SocialUser類的構(gòu)造函數(shù)。
  • 為特定于應(yīng)用程序的字段創(chuàng)建吸氣劑。
  • 添加一個(gè)內(nèi)部構(gòu)建器類,該類用于構(gòu)建新的ExampleUserDetails對(duì)象。
  • 我們的用戶詳細(xì)信息類的源代碼如下所示:

    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;}} }

    角色是一個(gè)簡(jiǎn)單的枚舉,它指定示例應(yīng)用程序的“合法”用戶角色。 其源代碼如下:

    public enum Role {ROLE_USER }

    SocialMediaService是一個(gè)枚舉,用于標(biāo)識(shí)用戶為我們的示例應(yīng)用程序創(chuàng)建用戶帳戶時(shí)使用的SaaS API提供程序。 其源代碼如下:

    public enum SocialMediaService {FACEBOOK,TWITTER }

    實(shí)現(xiàn)UserDetailsS??ervice接口

    通過執(zhí)行以下步驟,我們可以創(chuàng)建自己的UserDetailsS??ervice接口實(shí)現(xiàn):

  • 創(chuàng)建一個(gè)實(shí)現(xiàn)UserDetailsS??ervice接口的類。
  • 將UserRepository字段添加到創(chuàng)建的類。
  • 創(chuàng)建一個(gè)將UserRepository作為構(gòu)造函數(shù)參數(shù)的構(gòu)造函數(shù),并使用@Autowired注釋對(duì)構(gòu)造函數(shù)進(jìn)行注釋。
  • 實(shí)現(xiàn)UserDetailsS??ervice接口的loadUserByUsername(String username)方法。 此方法的實(shí)現(xiàn)包括以下步驟:
  • 通過調(diào)用UserRepository接口的findByEmail()方法來獲取用戶。 此方法返回其電子郵件與作為方法參數(shù)給出的用戶名匹配的用戶。
  • 如果找不到用戶,則拋出新的UsernameNotFoundException 。
  • 創(chuàng)建一個(gè)新的ExampleUserDetails對(duì)象。
  • 返回創(chuàng)建的對(duì)象。
  • RepositoryUserDetailsS??ervice類的源代碼如下所示:

    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;@Autowiredpublic RepositoryUserDetailsService(UserRepository repository) {this.repository = repository;}@Overridepublic 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;} }

    UserRepository是一個(gè)簡(jiǎn)單的Spring Data JPA存儲(chǔ)庫,其源代碼如下所示:

    import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository<User, Long> {public User findByEmail(String email); }

    該用戶是我們的示例應(yīng)用程序的唯一實(shí)體,它包含為我們的示例應(yīng)用程序創(chuàng)建了用戶帳戶的用戶的信息。 其源代碼的相關(guān)部分如下所示:

    import javax.persistence.*;@Entity @Table(name = "users") 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. }

    實(shí)現(xiàn)SocialUserDetailsS??ervice接口

    我們可以通過執(zhí)行以下步驟來實(shí)現(xiàn)SocialUserDetailsS??ervice接口:

  • 創(chuàng)建一個(gè)實(shí)現(xiàn)SocialUserDetailsS??ervice的類。
  • 將UserDetailsS??ervice字段添加到創(chuàng)建的類。
  • 創(chuàng)建一個(gè)將UserDetailsS??ervice對(duì)象作為構(gòu)造函數(shù)參數(shù)的構(gòu)造函數(shù),并使用@Autowired注釋對(duì)構(gòu)造函數(shù)進(jìn)行注釋。
  • 實(shí)現(xiàn)SocialUserDetailsInterface的loadUserByUserId(String userId)方法。
  • 通過調(diào)用loadUserByUsername()方法獲取正確的UserDetails對(duì)象,并將用戶ID作為方法參數(shù)傳遞。 我們可以這樣做是因?yàn)槲覀兊膽?yīng)用程序使用用戶的用戶名作為用戶ID。
  • 將返回的對(duì)象強(qiáng)制轉(zhuǎn)換為SocialUserDetails對(duì)象并返回。
  • SimpleSocialUserDetailsS??ervice類的源代碼如下所示:

    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;}@Overridepublic SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException, DataAccessException {UserDetails userDetails = userDetailsService.loadUserByUsername(userId);return (SocialUserDetails) userDetails;} }

    就這些。 現(xiàn)在,我們準(zhǔn)備配置應(yīng)用程序的應(yīng)用程序上下文。 讓我們找出如何做到這一點(diǎn)。

    配置應(yīng)用程序上下文

    本節(jié)介紹如何使用Java配置來配置示例應(yīng)用程序的應(yīng)用程序上下文。 遵循以下準(zhǔn)則,將應(yīng)用程序上下文配置分為多個(gè)配置類:

  • 每個(gè)配置類都包含與示例應(yīng)用程序的特定部分相關(guān)聯(lián)的配置。 如果我們必須在創(chuàng)建初始配置后的幾個(gè)月(或幾年)內(nèi)檢出某項(xiàng)內(nèi)容或進(jìn)行某些更改,則可以輕松找到相關(guān)的配置。
  • 對(duì)配置進(jìn)行了劃分,使之可以通過使用Spring Test MVC輕松編寫Web層的單元測(cè)試。 我們將在本教程的第三部分中進(jìn)一步討論這一點(diǎn),在該部分中,我們將為應(yīng)用程序的Web層編寫單元測(cè)試。
  • 當(dāng)我們?yōu)閼?yīng)用程序編寫集成測(cè)試時(shí),使用該配置可以輕松刪除對(duì)外部資源的依賴。 我們將在本教程的第四部分中進(jìn)一步討論這一點(diǎn),該教程描述了如何為應(yīng)用程序編寫集成測(cè)試。
  • 注意 :如果要使用XML配置,可以查看此博客文章的示例應(yīng)用程序,該示例應(yīng)用程序也具有有效的XML配置 (盡管沒有web.xml)。

    讓我們從配置應(yīng)用程序的持久層開始。

    配置持久層

    我們應(yīng)用程序的持久層存儲(chǔ)用戶帳戶信息,并提供一種訪問此信息的方法。 這很重要,原因有兩個(gè):

    • 我們可以提供一種使用用戶名和密碼登錄的方法。
    • 我們可以存儲(chǔ)特定于應(yīng)用程序的信息,并將此信息鏈接到使用社交登錄的用戶。

    讓我們找出如何通過使用兩個(gè)Java配置類來配置它。

    注意 :示例應(yīng)用程序的持久層使用Spring Data JPA 1.3.4。 我將使該部分盡可能的薄。 如果您想了解有關(guān)Spring Data JPA的更多信息,可以閱讀我的Spring Data JPA教程 。 我還寫了一本關(guān)于Spring Data的書,它應(yīng)該可以幫助您立即開始使用。

    我們可以按照以下步驟配置持久層:

  • 創(chuàng)建配置類,并使用@Configuration注釋對(duì)創(chuàng)建的類進(jìn)行注釋。
  • 用@EnableJpaRepositories批注為類注解,并設(shè)置Spring Data JPA信息庫的基本包。
  • 通過使用@EnableTransactionManagement批注注釋配置類來啟用Spring事務(wù)管理。
  • 在類中添加一個(gè)Environment字段,并使用@Autowired批注對(duì)該字段進(jìn)行批注。 我們不需要使用@PropertySource批注來配置屬性文件,因?yàn)橐呀?jīng)在“父”應(yīng)用程序上下文配置類中對(duì)其進(jìn)行了配置。
  • 配置數(shù)據(jù)源bean。 這個(gè)bean提供了到實(shí)體管理器的數(shù)據(jù)庫連接,但是它還有另一個(gè)目的。 當(dāng)Spring Social保持與數(shù)據(jù)庫的連接并從數(shù)據(jù)庫加載它們的連接時(shí),將使用它。
  • 配置事務(wù)管理器bean。
  • 配置實(shí)體管理器工廠bean。
  • PersistenceContext類的源代碼如下所示:

    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 {@Resourceprivate Environment env;@Beanpublic 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;}@Beanpublic JpaTransactionManager transactionManager() {JpaTransactionManager transactionManager = new JpaTransactionManager();transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());return transactionManager;}@Beanpublic 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;} }

    讓我們繼續(xù)研究如何為應(yīng)用程序創(chuàng)建安全配置。

    配置Spring Security

    Spring Security為使用表單登錄或社交登錄的用戶提供身份驗(yàn)證機(jī)制,并且還負(fù)責(zé)授權(quán)。

    我們可以按照以下步驟配置Spring Security:

  • 創(chuàng)建配置類,并使用@Configuration注釋對(duì)創(chuàng)建的類進(jìn)行注釋。
  • 用@EnableWebSecurity注釋對(duì)類進(jìn)行注釋。 這樣就可以通過實(shí)現(xiàn)WebSecurityConfigurer接口來配置Spring Security。
  • 確保我們的配置類擴(kuò)展了WebSecurityConfigurerAdapter類,該類是用于創(chuàng)建WebSecurityConfigurer實(shí)例的基類。 完成此操作后,我們可以通過覆蓋方法來自定義安全配置。
  • 將ApplicationContext字段添加到配置類,并使用@Autowired批注對(duì)該字段進(jìn)行批注。
  • 將UserRepository字段添加到配置中,并使用@Autowired注釋對(duì)該字段進(jìn)行注釋。
  • 重寫WebSecurityConfigurerAdapter類的configure(WebSecurity web)方法。 確保Spring Security忽略對(duì)靜態(tài)資源(例如CSS和Javascript文件)的請(qǐng)求。
  • 重寫WebSecurityConfigurerAdapter類的configure(HttpSecurity http)方法,并通過以下步驟實(shí)現(xiàn)它:
  • 通過執(zhí)行以下步驟配置表單登錄:
  • 將登錄頁面網(wǎng)址設(shè)置為“ / login”。
  • 將處理登錄表單提交的URL設(shè)置為“ / login / authenticate”。
  • 將登錄失敗網(wǎng)址設(shè)置為“ / login?error = bad_credentials”。
  • 通過執(zhí)行以下步驟配置注銷功能:
  • 確保注銷后刪除名為JSESSIONID的cookie。
  • 將注銷網(wǎng)址設(shè)置為“ / logout”。
  • 將注銷成功URL設(shè)置為“ / login”。
  • 配置基于url的授權(quán)。 此階段的主要目的是確保匿名用戶可以訪問與登錄/注冊(cè)過程相關(guān)的所有URL,并保護(hù)應(yīng)用程序的其余部分不受匿名用戶的攻擊。
  • 將SocialAuthenticationFilter添加到Spring Security過濾器鏈。 為此,我們可以創(chuàng)建一個(gè)新的SpringSocialConfigurer對(duì)象,并確保在配置Spring Security時(shí)使用該對(duì)象。
  • 將ApplicationContext字段的值設(shè)置為所有SecurityConfigurer實(shí)例共享的對(duì)象。
  • 配置用來對(duì)用戶密碼進(jìn)行哈希處理的PasswordEncoder bean(如果用戶使用表單注冊(cè)和登錄)。 我們可以通過創(chuàng)建一個(gè)新的BCryptPasswordEncoder對(duì)象并返回創(chuàng)建的對(duì)象來做到這一點(diǎn)。
  • 配置UserDetailsS??ervice Bean。 我們可以通過創(chuàng)建一個(gè)新的RepositoryUserDetailsS??ervice對(duì)象并將UserRepository作為構(gòu)造函數(shù)參數(shù)來實(shí)現(xiàn)。
  • 重寫WebSecurityConfigurerAdapter類的registerAuthentication(AuthenticationManagerBuilder auth)方法。 如果用戶使用表單登錄,我們將使用此方法配置身份驗(yàn)證請(qǐng)求。 通過執(zhí)行以下步驟來實(shí)現(xiàn)此方法:
  • 將UserDetailsS??ervice bean傳遞給作為方法參數(shù)給出的AuthenticationManagerBuilder對(duì)象。
  • 將PasswordEncoder bean傳遞給作為方法參數(shù)給出的AuthenticationManagerBuilder對(duì)象。
  • 配置SocialUserDetailsS??ervice bean。 我們可以通過創(chuàng)建一個(gè)新的SimpleSocialUserDetailsS??ervice對(duì)象并將UserDetailsS??ervice bean作為構(gòu)造函數(shù)參數(shù)來實(shí)現(xiàn)。 使用社交登錄時(shí),此bean加載用戶特定的數(shù)據(jù)。
  • 我們的應(yīng)用程序上下文配置類的源代碼如下所示:

    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 {@Autowiredprivate ApplicationContext context;@Autowiredprivate UserRepository userRepository;@Overridepublic void configure(WebSecurity web) throws Exception {web//Spring Security ignores request to static resources such as CSS or JS files..ignoring().antMatchers("/static/**");}@Overrideprotected 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","/signin/**","/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()).and().setSharedObject(ApplicationContext.class, context);}@Overrideprotected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(10);}@Beanpublic SocialUserDetailsService socialUserDetailsService() {return new SimpleSocialUserDetailsService(userDetailsService());}@Beanpublic UserDetailsService userDetailsService() {return new RepositoryUserDetailsService(userRepository);} }

    讓我們繼續(xù)前進(jìn),了解如何配置Spring Social。

    配置Spring Social

    Spring Social提供與Facebook和Twitter等SaaS API提供程序的集成。 我們可以按照以下步驟配置Spring Social:

  • 創(chuàng)建實(shí)現(xiàn)SocialConfigurer接口的應(yīng)用程序上下文配置類,并使用@Configuration注釋對(duì)創(chuàng)建的類進(jìn)行注釋。 SocialConfigurer接口聲明了可用于配置Spring Social的回調(diào)方法。
  • 用@EnableSocial批注對(duì)類進(jìn)行批注。 這將啟用Spring Social并導(dǎo)入SocialConfiguration配置類。
  • 用@Profile注釋為類添加注釋,并將字符串“ application”設(shè)置為其值。 這樣可以確保僅在活動(dòng)Spring概要文件為“ application”時(shí)使用此應(yīng)用程序上下文配置類。 這很重要,因?yàn)樗刮覀儫o需依賴Facebook或Twitter即可為我們的應(yīng)用程序編寫集成測(cè)試。
  • 將DataSource字段添加到配置類,并使用@Autowired批注對(duì)該字段進(jìn)行批注。
  • 將SocialConfigurer界面的addConnectionFactories()方法添加到創(chuàng)建的配置類中。 此方法采用以下兩個(gè)方法參數(shù):
  • 第一個(gè)參數(shù)是ConnectionFactoryConfigurer對(duì)象,可用于注冊(cè)連接工廠。
  • 第二個(gè)參數(shù)是一個(gè)Environment對(duì)象,它代表示例應(yīng)用程序在其中運(yùn)行的環(huán)境。
  • 通過執(zhí)行以下步驟來實(shí)現(xiàn)addConnectionFactories()方法:
  • 創(chuàng)建一個(gè)新的TwitterConnectionFactory對(duì)象,并將使用者密鑰和使用者密鑰作為構(gòu)造函數(shù)參數(shù)傳遞。
  • 通過調(diào)用ConnectionFactoryConfigurer接口的addConnectionFactory()方法來注冊(cè)創(chuàng)建的TwitterConnectionFactory對(duì)象。 將創(chuàng)建的TwitterConnectionFactory對(duì)象作為方法參數(shù)傳遞。
  • 創(chuàng)建一個(gè)新的FacebookConnectionFactory對(duì)象,并將應(yīng)用程序ID和應(yīng)用程序密鑰作為構(gòu)造函數(shù)參數(shù)傳遞。
  • 通過調(diào)用ConnectionFactoryConfigurer接口的addConnectionFactory方法來注冊(cè)創(chuàng)建的FacebookConnectionFactory對(duì)象。 將創(chuàng)建的FacebookConnectionFactory對(duì)象作為方法參數(shù)傳遞。
  • 將SocialConfigurer接口的getUserIdSource()方法添加到創(chuàng)建的類中。 此方法返回的UserIdSource對(duì)象負(fù)責(zé)確定用戶的正確帳戶ID。 因?yàn)槲覀兊氖纠龖?yīng)用程序使用用戶的用戶名作為帳戶ID,所以我們必須通過返回新的AuthenticationNameUserIdSource對(duì)象來實(shí)現(xiàn)此方法。
  • 將SocialConfigurer接口的getUsersConnectionRepository()方法添加到創(chuàng)建的類中。 此方法將ConnectionFactoryLocator對(duì)象作為方法參數(shù),并返回UsersConnectionRepository對(duì)象。
  • 通過執(zhí)行以下步驟來實(shí)現(xiàn)getUsersConnectionRepository()方法:
  • 創(chuàng)建一個(gè)新的JdbcUsersConnectionRepository對(duì)象,并將以下對(duì)象作為構(gòu)造函數(shù)參數(shù)傳遞:
  • 第一個(gè)參數(shù)是DataSource對(duì)象。 我們將dataSource字段的值作為第一個(gè)方法參數(shù)傳遞。
  • 第二個(gè)參數(shù)是ConnectionFactoryLocator對(duì)象。 我們將connectionFactoryLocator方法參數(shù)的值作為第二個(gè)方法參數(shù)傳遞。
  • 第三個(gè)參數(shù)是TextEncryptor對(duì)象,該對(duì)象加密SaaS API提供程序與我們的應(yīng)用程序之間建立的連接的授權(quán)詳細(xì)信息。 我們通過調(diào)用Encryptors類的noOpText()方法來創(chuàng)建此對(duì)象。 這意味著我們的示例應(yīng)用程序?qū)⑦@些詳細(xì)信息存儲(chǔ)為純文本。 這在開發(fā)階段很方便,但是我們不應(yīng)該在生產(chǎn)中使用它
  • 返回創(chuàng)建的對(duì)象。
  • 配置ConnectController bean。 配置此bean的方法有兩個(gè)參數(shù)。 第一個(gè)參數(shù)是ConnectionFactoryLocator bean。 第二個(gè)參數(shù)是使用的ConnectionRepository bean。 在創(chuàng)建新的ConnectController對(duì)象時(shí),將這些參數(shù)作為構(gòu)造函數(shù)參數(shù)傳遞。
  • 我們的配置類的源代碼如下所示:

    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 @Profile("application") public class SocialContext implements SocialConfigurer {@Autowiredprivate DataSource dataSource;@Overridepublic 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")));}@Overridepublic UserIdSource getUserIdSource() {return new AuthenticationNameUserIdSource();}@Overridepublic UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {return new JdbcUsersConnectionRepository(dataSource,connectionFactoryLocator,Encryptors.noOpText());}@Beanpublic ConnectController connectController(ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) {return new ConnectController(connectionFactoryLocator, connectionRepository);} }

    下一步是配置應(yīng)用程序的Web層。 讓我們開始工作。

    配置Web層

    我們可以按照以下步驟配置應(yīng)用程序的Web層:

  • 通過執(zhí)行以下步驟來創(chuàng)建配置類:
  • 擴(kuò)展WebMvcConfigurerAdapter類。
  • 用@Configuration注釋對(duì)創(chuàng)建的類進(jìn)行注釋。
  • 通過使用@ComponentScan批注注釋該類并設(shè)置控制器的基本軟件包,確保找到所有控制器類。
  • 通過使用@EnableWebMvc注釋對(duì)類進(jìn)行注釋來啟用注釋驅(qū)動(dòng)的Web mvc。
  • 確保容器的默認(rèn)Servlet提供靜態(tài)資源。
  • 通過重寫WebMvcConfigurerAdapter類的addResourceHandlers()方法來配置靜態(tài)資源。
  • 確保對(duì)靜態(tài)資源的請(qǐng)求被轉(zhuǎn)發(fā)到容器的默認(rèn)Servlet。 這是通過重寫WebMvcConfigurerAdapter類的configureDefaultServletHandling()方法來完成的。
  • 配置異常解析器 bean。
  • 配置ViewResolver bean。
  • WebAppContext類的源代碼如下所示:

    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 {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static/**").addResourceLocations("/static/");}@Overridepublic void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();}@Beanpublic 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;}@Beanpublic ViewResolver viewResolver() {InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();viewResolver.setViewClass(JstlView.class);viewResolver.setPrefix("/WEB-INF/jsp/");viewResolver.setSuffix(".jsp");return viewResolver;} }

    讓我們找出如何將所有這些結(jié)合在一起,并為我們的應(yīng)用程序創(chuàng)建一個(gè)“父”應(yīng)用程序上下文配置類。

    綁在一起

    最后一個(gè)應(yīng)用程序上下文配置類具有三個(gè)職責(zé):

  • 它配置了整個(gè)示例應(yīng)用程序中使用的常規(guī)組件。
  • 它確保在類路徑掃描期間找到我們應(yīng)用程序的服務(wù)類。
  • 它是我們應(yīng)用程序的根應(yīng)用程序上下文配置類。
  • 我們可以按照以下步驟創(chuàng)建此配置類:

  • 創(chuàng)建配置類,并使用@Configuration注釋對(duì)創(chuàng)建的類進(jìn)行注釋。
  • 通過使用@ComponentScan批注注釋該類并設(shè)置我們的服務(wù)的基本包,確保在組件掃描期間找到我們的服務(wù)類。
  • 通過使用@Import批注對(duì)類進(jìn)行導(dǎo)入,以導(dǎo)入其他應(yīng)用程序上下文配置類。
  • 用@PropertySource注釋對(duì)類進(jìn)行注釋,并將其配置為從類路徑中查找名為application.properties的屬性文件。 這樣可以確保可以在導(dǎo)入的應(yīng)用程序上下文配置類中訪問配置屬性。
  • 配置MessageSource bean。
  • 配置PropertyPlaceHolderConfigurer bean。
  • ExampleApplicationContext類的源代碼如下所示:

    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 {@Beanpublic MessageSource messageSource() {ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();messageSource.setBasename("i18n/messages");messageSource.setUseCodeAsDefaultMessage(true);return messageSource;}@Beanpublic PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {return new PropertySourcesPlaceholderConfigurer();} }

    現(xiàn)在,我們已經(jīng)配置了示例應(yīng)用程序的應(yīng)用程序上下文。 但是,我們?nèi)匀槐仨毰渲肳eb應(yīng)用程序。 讓我們看看如何使用Java配置來做到這一點(diǎn)。

    配置Web應(yīng)用程序

    我們的最后一步是配置示例應(yīng)用程序。 只要將應(yīng)用程序部署到Servlet 3.0兼容容器中,我們就可以在沒有web.xml的情況下執(zhí)行此操作。

    我們可以按照以下步驟配置Web應(yīng)用程序:

  • 創(chuàng)建一個(gè)實(shí)現(xiàn)WebApplicationInitializer接口的類。
  • 通過覆蓋WebApplicationInitializer接口的onStartup()方法來配置我們的應(yīng)用程序。 我們可以通過執(zhí)行以下步驟來實(shí)現(xiàn)此方法:
  • 創(chuàng)建應(yīng)用程序的根上下文,并將ExampleApplicationContext類注冊(cè)到創(chuàng)建的根上下文。
  • 配置調(diào)度程序servlet 。
  • C)配置字符編碼過濾器 。
    D)配置Spring Security過濾器鏈 。
    E)配置Sitemesh 。 F)將上下文加載器偵聽器添加到Servlet上下文。

    ExampleApplicationConfig類的源代碼如下所示:

    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 {@Overridepublic 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));} }

    下一步是什么?

    現(xiàn)在,我們已經(jīng)使用Java配置成功配置了示例應(yīng)用程序。 本教程教了我們兩件事:

    • 我們學(xué)習(xí)了如何實(shí)現(xiàn)Spring Security和Spring Social所需的組件。
    • 我們學(xué)習(xí)了通過使用Java配置來集成Spring Security和Spring Social。

    本教程的下一部分描述了如何向示例應(yīng)用程序添加注冊(cè)和身份驗(yàn)證功能。

    PS與往常一樣,此博客文章的示例應(yīng)用程序可在Github上獲得 。

    參考: 在Spring MVC Web應(yīng)用程序中添加社交登錄:來自Petri Kainulainen博客的JCG合作伙伴 Petri Kainulainen進(jìn)行的配置 。

    翻譯自: https://www.javacodegeeks.com/2013/10/adding-social-sign-in-to-a-spring-mvc-web-application-configuration.html

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的将社交登录添加到Spring MVC Web应用程序:配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。