javascript
将社交登录添加到Spring MVC Web应用程序:配置
過去,用戶使用用戶名和密碼組合登錄。 盡管如今有些人仍然偏愛傳統(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)建屬性文件:
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)行操作:
我們的用戶詳細(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):
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接口:
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è)配置類:
注意 :如果要使用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)該可以幫助您立即開始使用。
我們可以按照以下步驟配置持久層:
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:
我們的應(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:
我們的配置類的源代碼如下所示:
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層:
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é):
我們可以按照以下步驟創(chuàng)建此配置類:
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)用程序:
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上獲得 。
翻譯自: 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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编程linux系统哪个版本好(编程lin
- 下一篇: 在WildFly中将Apache Cam