Đăng Nhập Bằng Mạng Xã Hội Trong Spring MVC Với Spring Social ...
Có thể bạn quan tâm
- Tất cả tài liệu
- Java
- Java Basic
- Java Collections Framework
- Java IO
- Java New IO
- Java Date Time
- Servlet/JSP
- Eclipse Tech
- SWT
- RCP
- RAP
- Eclipse Plugin Tools
- XML & HTML
- Java Opensource
- Java Application Servers
- Maven
- Gradle
- Servlet/Jsp
- Thymeleaf
- Spring
- Spring Boot
- Spring Cloud
- Struts2
- Hibernate
- Java Web Service
- JavaFX
- SWT
- Oracle ADF
- Android
- iOS
- Python
- Swift
- C#
- C/C++
- Ruby
- Dart
- Batch
- Database
- Oracle
- MySQL
- SQL Server
- PostGres
- Other Database
- Oracle APEX
- Report
- Client
- ECMAScript / Javascript
- TypeScript
- NodeJS
- ReactJS
- Flutter
- AngularJS
- HTML
- CSS
- Bootstrap
- OS
- Ubuntu
- Solaris
- Mac OS
- VPS
- Git
- SAP
- Amazon AWS
- Khác
- Chưa phân loại
- Phần mềm & ứng dụng tiện ích
- VirtualBox
- VmWare
- Các bảng
- Mô hình đăng nhập
- Đăng ký Oauth2
- Cấu hình web.xml và Maven
- Cấu hình Spring MVC và Security
- User, User Serivce, User DAO
- Các lớp cho việc đăng ký tài khoản (SignUp)
- Controller
- Các trang JSP
- Chạy ứng dụng
Xem thêm:
- Ví dụ OAuth2 Social Login trong Spring Boot
1. Các bảng
Trước hết bạn cần tạo các bảng:** ORACLE **-- Create table create table USERCONNECTION ( USERID VARCHAR2(255) not null, PROVIDERID VARCHAR2(255) not null, PROVIDERUSERID VARCHAR2(255) not null, RANK INTEGER not null, DISPLAYNAME VARCHAR2(255), PROFILEURL VARCHAR2(512), IMAGEURL VARCHAR2(512), ACCESSTOKEN VARCHAR2(255) not null, SECRET VARCHAR2(255), REFRESHTOKEN VARCHAR2(255), EXPIRETIME NUMBER(19) ) ; -- Create/Recreate primary, unique and foreign key constraints alter table USERCONNECTION add primary key (USERID, PROVIDERID, PROVIDERUSERID) ; -- Create/Recreate indexes create unique index USERCONNECTIONRANK on USERCONNECTION (USERID, PROVIDERID, RANK) ; ----------------------------------------- Create table create table USER_ACCOUNTS ( ID VARCHAR2(255) not null, EMAIL VARCHAR2(100) not null, USER_NAME VARCHAR2(100) not null, FIRST_NAME VARCHAR2(100) not null, LAST_NAME VARCHAR2(100) not null, PASSWORD VARCHAR2(255), ROLE VARCHAR2(20) not null, ENABLED VARCHAR2(1) default 'Y' not null ) ; -- Create/Recreate primary, unique and foreign key constraints alter table USER_ACCOUNTS add primary key (ID) ; alter table USER_ACCOUNTS add constraint User_Account_UK1 unique (EMAIL); alter table USER_ACCOUNTS add constraint User_Account_UK2 unique (USER_NAME);** MYSQL/SQL SERVER **-- Create table create table USERCONNECTION ( USERID VARCHAR(255) not null, PROVIDERID VARCHAR(255) not null, PROVIDERUSERID VARCHAR(255) not null, RANK INTEGER not null, DISPLAYNAME VARCHAR(255), PROFILEURL VARCHAR(512), IMAGEURL VARCHAR(512), ACCESSTOKEN VARCHAR(255) not null, SECRET VARCHAR(255), REFRESHTOKEN VARCHAR(255), EXPIRETIME BIGINT ) ; -- Create/Recreate primary, unique and foreign key constraints alter table USERCONNECTION add primary key (USERID, PROVIDERID, PROVIDERUSERID) ; -- Create/Recreate indexes create unique index USERCONNECTIONRANK on USERCONNECTION (USERID, PROVIDERID, RANK) ; ----------------------------------------- -- Create table create table USER_ACCOUNTS ( ID VARCHAR(255) not null, EMAIL VARCHAR(100) not null, USER_NAME VARCHAR(100) not null, FIRST_NAME VARCHAR(100) not null, LAST_NAME VARCHAR(100) not null, PASSWORD VARCHAR(255), ROLE VARCHAR(20) not null, ENABLED VARCHAR(1) default 'Y' not null ) ; -- Create/Recreate primary, unique and foreign key constraints alter table USER_ACCOUNTS add primary key (ID) ; alter table USER_ACCOUNTS add constraint User_Account_UK1 unique (EMAIL); alter table USER_ACCOUNTS add constraint User_Account_UK2 unique (USER_NAME);
USERCONNECTION & USER_ACCOUNTSNếu bạn có sẵn một ứng dụng Web Spring, và đăng nhập vào hệ thống này thông qua các tài khoản được lưu trong một bảng, chẳng hạn USER_ACCOUNTS. (Chú ý rằng có thể cấu trúc bảng Users của bạn có thể khác với cấu trúc của bảng này).Bạn có thể tích hợp chức năng đăng nhập thông qua mạng xã hội vào Website của bạn. Bạn cần tạo ra một bảng USERCONNECTION. Chú ý rằng cấu trúc của bảng này được cung cấp bởi Spring Social Security API, vì vậy việc insert, update dữ liệu vào bảng này được hỗ trợ bởi API này. Tuy nhiên bạn cũng cũng có thể tùy biến cấu trúc của nó.Chú ý: Việc insert, update vào bảng USERCONNECTION được thực hiện bởi lớp JdbcUsersConnectionRepository của Spring Social Security API.Dữ liệu ví dụ:

2. Mô hình đăng nhập
Trường hợp người dùng login bằng mạng xã hội, ứng dụng của bạn yêu cầu người dùng cho phép truy cập các thông tin cơ bản (tên, email,..). Nếu người dùng không đồng ý, chương trình sẽ chuyển hướng tới trang /signin để người dùng đăng nhập theo cách thông thường.
Trong trường hợp người dùng cho phép ứng dụng truy cập các thông tin cơ bản của họ, có hai mô hình hoạt động, được minh họa dưới đây:Mô hình 1 : Hiển thị trang đăng ký sau khi đăng nhập mạng xã hộiSau khi người dùng đăng nhập vào thông qua mạng xã hội, bạn sẽ có UserProfile, nó là một đối tượng lưu trữ thông tin cơ bản của người dùng và thông tin mạng xã hội, bạn có thể tìm thấy userID trong bảng USERCONNECTION ứng với các thông tin UserProfile, và tìm bản ghi USER_ACCOUNTS tương ứng với userID, Nếu không có bản ghi tương ứng trong bảng USER_ACCOUNTS, nó sẽ chuyển hướng tới trang đăng ký. Sau khi người dùng đăng ký, một bản ghi USER_ACCOUNTS được tạo ra, đồng thời một bản ghi USERCONNECTION cũng được ta. Và tự động đăng nhập vào website.
Mô hình 2: Tự động tạo tài khoản sau khi đăng nhập mạng xã hộiMô hình này gần giống với Mô hình 1 ở trên, nếu không tìm thấy bản ghi USERCONNECTIONS tương ứng với UserProfile, một bản ghi User_Accounts sẽ được tạo ra, đồng thời tạo một bản ghi USERCONNECTION.
3. Đăng ký Oauth2
Nếu bạn muốn đăng nhập sử dụng Google bạn cần có Client ID, và Password và khai báo các Redirect URL mà ứng dụng của bạn có thể chuyển hướng tới khi người dùng đăng nhập thành công Google. Xem hướng dẫn chi tiết tại:- Tạo Google API Console Project và OAuth2 Client ID
- Tạo Facebook Developers Application và Oauth2 App ID
4. Cấu hình web.xml và Maven
web.xml<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Spring Social Security</display-name> </web-app>pom.xml<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.o7planning</groupId> <artifactId>SpringMVCSocialJdbc</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>SpringMVCSocialJdbc Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <!-- Generic properties --> <java.version>1.7</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <repositories> <!-- Repository for ORACLE JDBC Driver --> <repository> <id>codelds</id> <url>https://code.lds.org/nexus/content/groups/main-repo</url> </repository> </repositories> <dependencies> <!-- Spring framework START --> <!-- http://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!-- Spring framework END --> <!-- Spring Security Artifacts - START --> <!-- http://mvnrepository.com/artifact/org.springframework.security/spring-security-web --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>4.0.4.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.security/spring-security-config --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>4.0.4.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>4.1.0.RELEASE</version> </dependency> <!-- Spring Security Artifacts - END --> <!-- Jstl for jsp page --> <!-- http://mvnrepository.com/artifact/javax.servlet/jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Servlet API --> <!-- http://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- JSP API --> <!-- http://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> <!-- MySQL JDBC driver --> <!-- http://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> </dependency> <!-- Oracle JDBC driver --> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> </dependency> <!-- SQLServer JDBC driver (JTDS) --> <!-- http://mvnrepository.com/artifact/net.sourceforge.jtds/jtds --> <dependency> <groupId>net.sourceforge.jtds</groupId> <artifactId>jtds</artifactId> <version>1.3.1</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.social/spring-social-config --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-config</artifactId> <version>1.1.4.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.social/spring-social-core --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-core</artifactId> <version>1.1.4.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.social/spring-social-security --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-security</artifactId> <version>1.1.4.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.social/spring-social-web --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-web</artifactId> <version>1.1.4.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.social/spring-social-facebook --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-facebook</artifactId> <version>2.0.3.RELEASE</version> <exclusions> <exclusion> <artifactId>spring-social-core</artifactId> <groupId>org.springframework.social</groupId> </exclusion> <exclusion> <artifactId>spring-social-config</artifactId> <groupId>org.springframework.social</groupId> </exclusion> </exclusions> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.social/spring-social-google --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-google</artifactId> <version>1.0.0.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.social/spring-social-twitter --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-twitter</artifactId> <version>1.1.2.RELEASE</version> </dependency> <!-- http://mvnrepository.com/artifact/org.springframework.social/spring-social-linkedin --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-linkedin</artifactId> <version>1.0.2.RELEASE</version> </dependency> <!-- Email validator,... --> <!-- http://mvnrepository.com/artifact/commons-validator/commons-validator --> <dependency> <groupId>commons-validator</groupId> <artifactId>commons-validator</artifactId> <version>1.5.0</version> </dependency> </dependencies> <build> <finalName>SpringMVCSocialJdbc</finalName> <plugins> <!-- Config: Maven Tomcat Plugin --> <!-- http://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <!-- Config: contextPath and Port (Default: /SpringMVCSocialJdbc : 8080) --> <!-- <configuration> <path>/</path> <port>8899</port> </configuration> --> </plugin> </plugins> </build> </project>5. Cấu hình Spring MVC và Security
ApplicationContextConfig.javapackage org.o7planning.socialsecurity.config; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.core.env.Environment; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @ComponentScan("org.o7planning.socialsecurity.*") @EnableTransactionManagement // Load to Environment. @PropertySource("classpath:datasource-cfg.properties") public class ApplicationContextConfig { // The Environment class serves as the property holder // and stores all the properties loaded by the @PropertySource // Lưu trữ các giá thuộc tính load bởi @PropertySource. @Autowired private Environment env; @Bean public ResourceBundleMessageSource messageSource() { ResourceBundleMessageSource rb = new ResourceBundleMessageSource(); // Load property in message/validator.properties rb.setBasenames(new String[] { "messages/validator" }); return rb; } @Bean(name = "viewResolver") public InternalResourceViewResolver getViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/pages/"); viewResolver.setSuffix(".jsp"); return viewResolver; } @Bean(name = "dataSource") public DataSource getDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); // See: datasouce-cfg.properties // Xem: datasouce-cfg.properties dataSource.setDriverClassName(env.getProperty("ds.database-driver")); dataSource.setUrl(env.getProperty("ds.url")); dataSource.setUsername(env.getProperty("ds.username")); dataSource.setPassword(env.getProperty("ds.password")); System.out.println("## getDataSource: " + dataSource); return dataSource; } // Transaction Manager @Autowired @Bean(name = "transactionManager") public DataSourceTransactionManager getTransactionManager(DataSource dataSource) { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); return transactionManager; } }SpringWebAppInitializer.javapackage org.o7planning.socialsecurity.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class SpringWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext(); appContext.register(ApplicationContextConfig.class); ServletRegistration.Dynamic dispatcher = servletContext.addServlet("SpringDispatcher", new DispatcherServlet(appContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } }WebMvcConfig.javapackage org.o7planning.socialsecurity.config; import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; 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; @Configuration @EnableWebMvc public class WebMvcConfig extends WebMvcConfigurerAdapter { private static final Charset UTF8 = Charset.forName("UTF-8"); // Cấu hình UTF-8 cho các trang. @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(); stringConverter.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "plain", UTF8))); converters.add(stringConverter); // Add other converters ... } // Cấu hình để sử dụng các file nguồn tĩnh (html, image, ..) // Tương đương với <mvc:resources/> trong cấu hình sử dụng XML. @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(31556926); registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(31556926); registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926); } // Tương đương cấu hình trong xml. @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }Thông tin database:datasource-cfg.properties (** For ORACLE DB)# DataSource ds.database-driver=oracle.jdbc.driver.OracleDriver ds.url=jdbc:oracle:thin:@localhost:1521:db12c ds.username=oauth2 ds.password=oauth2datasource-cfg.properties (** For MYSQL DB)# DataSource ds.database-driver=com.mysql.jdbc.Driver ds.url=jdbc:mysql://localhost:3306/oauth2 ds.username=root ds.password=12345datasource-cfg.properties (** For SQL SERVER DB)# DataSource ds.database-driver=net.sourceforge.jtds.jdbc.Driver ds.url=jdbc:jtds:sqlserver://localhost:1433/simplehr;instance=SQLEXPRESS ds.username=oauth2 ds.password=12345Cấu hình Security:SpringSecurityInitializer.javapackage org.o7planning.socialsecurity.config; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; // Config: Spring Security Filter. public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer { // Do nothing }WebSecurityConfig.javapackage org.o7planning.socialsecurity.config; import org.o7planning.socialsecurity.service.MyUserDetailsService; import org.springframework.beans.factory.annotation.Autowired; 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.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.social.security.SpringSocialConfigurer; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MyUserDetailsService myUserDetailsService; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { // Sét đặt Service tải thông tin các User trong DB. auth.userDetailsService(myUserDetailsService); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); // Các trang không yêu cầu login http.authorizeRequests().antMatchers("/", "/signup", "/login", "/logout").permitAll(); // Trang /userInfo yêu cầu phải login với vai trò ROLE_USER // Nếu chưa login, nó sẽ redirect tới trang /login. http.authorizeRequests().antMatchers("/userInfo").access("hasRole('ROLE_USER')"); // Form Login config http.authorizeRequests().and().formLogin()// // Submit URL of login page. .loginProcessingUrl("/j_spring_security_check") // Submit URL .loginPage("/login")// .defaultSuccessUrl("/userInfo")// .failureUrl("/login?error=true")// .usernameParameter("username")// .passwordParameter("password"); // Logout Config http.authorizeRequests().and().logout().logoutUrl("/logout").logoutSuccessUrl("/"); // Spring Social Config. http.apply(new SpringSocialConfigurer()) // .signupUrl("/signup"); } // This bean is load the user specific data when form login is used. @Override public UserDetailsService userDetailsService() { return myUserDetailsService; } }Cấu hình Spring Social Security:SocialConfig.javapackage org.o7planning.socialsecurity.config; import javax.sql.DataSource; import org.o7planning.socialsecurity.dao.MyUserAccountDAO; import org.o7planning.socialsecurity.signup.MyConnectionSignUp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; 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.ConnectionSignUp; 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.google.connect.GoogleConnectionFactory; import org.springframework.social.linkedin.connect.LinkedInConnectionFactory; import org.springframework.social.security.AuthenticationNameUserIdSource; import org.springframework.social.twitter.connect.TwitterConnectionFactory; @Configuration @EnableSocial // Load to Environment. @PropertySource("classpath:social-cfg.properties") public class SocialConfig implements SocialConfigurer { private boolean autoSignUp = false; @Autowired private DataSource dataSource; @Autowired private MyUserAccountDAO myUserAccountDAO; // @env: Đọc vào file properties cấu hình bởi @PropertySource @Override public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) { // Twitter TwitterConnectionFactory tfactory = new TwitterConnectionFactory(// env.getProperty("twitter.consumer.key"), // env.getProperty("twitter.consumer.secret")); // tfactory.setScope(env.getProperty("twitter.scope")); cfConfig.addConnectionFactory(tfactory); // Facebook FacebookConnectionFactory ffactory = new FacebookConnectionFactory(// env.getProperty("facebook.app.id"), // env.getProperty("facebook.app.secret")); ffactory.setScope(env.getProperty("facebook.scope")); // auth_type=reauthenticate cfConfig.addConnectionFactory(ffactory); // Linkedin LinkedInConnectionFactory lfactory = new LinkedInConnectionFactory(// env.getProperty("linkedin.consumer.key"), // env.getProperty("linkedin.consumer.secret")); lfactory.setScope(env.getProperty("linkedin.scope")); cfConfig.addConnectionFactory(lfactory); // Google GoogleConnectionFactory gfactory = new GoogleConnectionFactory(// env.getProperty("google.client.id"), // env.getProperty("google.client.secret")); gfactory.setScope(env.getProperty("google.scope")); cfConfig.addConnectionFactory(gfactory); } // The UserIdSource determines the userID of the user. @Override public UserIdSource getUserIdSource() { return new AuthenticationNameUserIdSource(); } // Đọc và ghi vào bảng USERCONNECTION. @Override public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) { // org.springframework.social.security.SocialAuthenticationServiceRegistry JdbcUsersConnectionRepository usersConnectionRepository = new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText()); if (autoSignUp) { // Cấu hình để: // Sau khi đăng nhập vào mạng xã hội. // Tự động tạo ra USER_ACCOUNT tương ứng nếu chưa có. ConnectionSignUp connectionSignUp = new MyConnectionSignUp(myUserAccountDAO); usersConnectionRepository.setConnectionSignUp(connectionSignUp); } else { // Cấu hình để: // Sau khi đăng nhập vào mạng xã hội. // Nếu không tìm thấy bản ghi USER_ACCOUNT tương ứng // Chuyển tới trang đăng ký. usersConnectionRepository.setConnectionSignUp(null); } return usersConnectionRepository; } // This bean manages the connection flow between the account provider and // the example application. @Bean public ConnectController connectController(ConnectionFactoryLocator connectionFactoryLocator, // ConnectionRepository connectionRepository) { return new ConnectController(connectionFactoryLocator, connectionRepository); } }Cấu hình mạng xã hội:
social-cfg.properties# Twitter # http://localhost:8080/SpringMVCSocialJdbc/auth/twitter twitter.consumer.key= twitter.consumer.secret= twitter.scope= # Facebook # http://localhost:8080/SpringMVCSocialJdbc/auth/facebook facebook.app.id=1084911261562762 facebook.app.secret=81a324fdbc4cade1ee25523c7bff58b3 facebook.scope=public_profile,email # Linkedin # http://localhost:8080/SpringMVCSocialJdbc/auth/linkedin linkedin.consumer.key=... linkedin.consumer.secret=... linkedin.scope= # Google # http://localhost:8080/SpringMVCSocialJdbc/auth/google google.client.id=160790488111-he5fn6rq0foqg05te70dk25gifeoum9s.apps.googleusercontent.com google.client.secret=VILTmX1UjOnyw2_meYvDQEdl google.scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profileChú ý: Để login mạng xã hội Google, bạn phải bật (enable) chức năng Google+ API:
6. User, User Serivce, User DAO
MyUserAccount là lớp đại diện cho một bản ghi trong bảng USER_ACCOUNTS trong DB.MyUserAccount.javapackage org.o7planning.socialsecurity.model; public class MyUserAccount { public static final String ROLE_USER = "ROLE_USER"; private String id; private String email; private String userName; private String firstName; private String lastName; private String password; private String role; public MyUserAccount() { } public MyUserAccount(String id, String email,String userName, String firstName, // String lastName, String password, // String role) { this.id = id; this.email = email; this.userName= userName; this.firstName = firstName; this.lastName = lastName; this.password = password; this.role = role; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } }MyUserAccountMapper là lớp giúp ánh xạ (mapping) giữa các trường (field) của lớp MyUserAccount với các cột của bảng USER_ACCOUNTS.MyUserAccountMapper.javapackage org.o7planning.socialsecurity.mapper; import java.sql.ResultSet; import java.sql.SQLException; import org.o7planning.socialsecurity.model.MyUserAccount; import org.springframework.jdbc.core.RowMapper; public class MyUserAccountMapper implements RowMapper<MyUserAccount> { @Override public MyUserAccount mapRow(ResultSet rs, int rowNum) throws SQLException { String id = rs.getString("id"); String email = rs.getString("email"); String userName= rs.getString("user_name"); String firstName = rs.getString("first_name"); String lastName = rs.getString("last_name"); String password = rs.getString("password"); String role = rs.getString("role"); return new MyUserAccount(id, email,userName, firstName, // lastName, password, // role ); } }MyUserAccountDAO.javapackage org.o7planning.socialsecurity.dao; import java.util.UUID; import javax.sql.DataSource; import org.o7planning.socialsecurity.form.MyUserAccountForm; import org.o7planning.socialsecurity.mapper.MyUserAccountMapper; import org.o7planning.socialsecurity.model.MyUserAccount; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.support.JdbcDaoSupport; import org.springframework.social.connect.Connection; import org.springframework.social.connect.ConnectionKey; import org.springframework.social.connect.UserProfile; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @Repository @Transactional public class MyUserAccountDAO extends JdbcDaoSupport { @Autowired public MyUserAccountDAO(DataSource dataSource) { this.setDataSource(dataSource); } public MyUserAccount findById(String id) { String sql = "Select id,email,user_name, first_name,last_name,"// + " password,role"// + " from User_Accounts u "// + " where id = ? "; Object[] params = new Object[] { id }; MyUserAccountMapper mapper = new MyUserAccountMapper(); try { MyUserAccount userInfo = this.getJdbcTemplate().queryForObject(sql, params, mapper); return userInfo; } catch (EmptyResultDataAccessException e) { return null; } } public MyUserAccount findByEmail(String email) { String sql = "Select id, email,user_name,first_name,last_name,"// + " password,role"// + " from User_Accounts u "// + " where email = ? "; Object[] params = new Object[] { email }; MyUserAccountMapper mapper = new MyUserAccountMapper(); try { MyUserAccount userInfo = this.getJdbcTemplate().queryForObject(sql, params, mapper); return userInfo; } catch (EmptyResultDataAccessException e) { return null; } } public MyUserAccount findByUserName(String userName) { String sql = "Select id, email,user_name,first_name,last_name,"// + " password,role"// + " from User_Accounts u "// + " where user_name = ? "; Object[] params = new Object[] { userName }; MyUserAccountMapper mapper = new MyUserAccountMapper(); try { MyUserAccount userInfo = this.getJdbcTemplate().queryForObject(sql, params, mapper); return userInfo; } catch (EmptyResultDataAccessException e) { return null; } } public MyUserAccount registerNewUserAccount(MyUserAccountForm accountForm) { String sql = "Insert into User_Accounts "// + " (id, email,user_name,first_name,last_name,password,role) "// + " values (?,?,?,?,?,?,?) "; // String ngẫu nhiên 36 ký tự. String id = UUID.randomUUID().toString(); this.getJdbcTemplate().update(sql, id, accountForm.getEmail(), // accountForm.getUserName(), // accountForm.getFirstName(), accountForm.getLastName(), // accountForm.getPassword(), MyUserAccount.ROLE_USER); return findById(id); } // Tự động tạo ra User Account. public MyUserAccount createUserAccount(Connection<?> connection) { ConnectionKey key = connection.getKey(); // (facebook,12345), (google,123) ... System.out.println("key= (" + key.getProviderId() + "," + key.getProviderUserId() + ")"); UserProfile userProfile = connection.fetchUserProfile(); String email = userProfile.getEmail(); MyUserAccount account = this.findByEmail(email); if (account != null) { return account; } // Tạo mới User_Account. String sql = "Insert into User_Accounts "// + " (id, email,user_name,first_name,last_name,password,role) "// + " values (?,?,?,?,?,?,?) "; // String ngẫu nhiên 36 ký tự. String id = UUID.randomUUID().toString(); String userName_prefix = userProfile.getFirstName().trim().toLowerCase()// +"_"+ userProfile.getLastName().trim().toLowerCase(); String userName = this.findAvailableUserName(userName_prefix); this.getJdbcTemplate().update(sql, id, email, userName, // userProfile.getFirstName(), userProfile.getLastName(), // "123", MyUserAccount.ROLE_USER); return findById(id); } private String findAvailableUserName(String userName_prefix) { MyUserAccount account = this.findByUserName(userName_prefix); if (account == null) { return userName_prefix; } int i = 0; while (true) { String userName = userName_prefix + "_" + i++; account = this.findByUserName(userName); if (account == null) { return userName; } } } }MySocialUserDetails là lớp thực hiện interface SocialUserDetails, chú ý SocialUserDetails là interface mở rộng từ interface UserDetails. Việc login thông qua mạng xã hội sử dụng Spring MVC Social API về bản chất là dựa trên Spring Security API.MySocialUserDetails.javapackage org.o7planning.socialsecurity.user; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.o7planning.socialsecurity.model.MyUserAccount; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.social.security.SocialUserDetails; public class MySocialUserDetails implements SocialUserDetails { private static final long serialVersionUID = -5246117266247684905L; private List<GrantedAuthority> list = new ArrayList<GrantedAuthority>(); private MyUserAccount myUserAccount; public MySocialUserDetails(MyUserAccount myUserAccount) { this.myUserAccount = myUserAccount; String role = myUserAccount.getRole(); GrantedAuthority grant = new SimpleGrantedAuthority(role); this.list.add(grant); } @Override public String getUserId() { return this.myUserAccount.getId(); } @Override public String getUsername() { return myUserAccount.getUserName(); } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return list; } @Override public String getPassword() { return myUserAccount.getPassword(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }MyUserDetailsService là dịch vụ được sử dụng bởi Spring Security API để lấy thông tin người dùng từ Database.MyUserDetailsService.javapackage org.o7planning.socialsecurity.service; import org.o7planning.socialsecurity.dao.MyUserAccountDAO; import org.o7planning.socialsecurity.model.MyUserAccount; import org.o7planning.socialsecurity.user.MySocialUserDetails; 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; import org.springframework.social.security.SocialUserDetails; import org.springframework.stereotype.Service; // Lấy thông tin User dưới database. @Service public class MyUserDetailsService implements UserDetailsService { @Autowired private MyUserAccountDAO myUserAccountDAO; public MyUserDetailsService() { } // (Phương thức này được sử dụng bởi Spring Security API). @Override public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { MyUserAccount myUserAccount = myUserAccountDAO.findByUserName(userName); if (myUserAccount == null) { throw new UsernameNotFoundException("No user found with userName: " + userName); } // Chú ý: SocialUserDetails mở rộng từ interface UserDetails. SocialUserDetails principal = new MySocialUserDetails(myUserAccount); return principal; } }SocialUserDetailsService là dịch vụ được sử dụng bởi Spring Social Security API, để tải thông tin người dùng (đăng nhập bởi mạng xã hội) từ Database.Spring Social Security API là một API dựa trên Spring Security API, nó không thay thế Spring Security API.MySocialUserDetailsService.javapackage org.o7planning.socialsecurity.service; import org.o7planning.socialsecurity.user.MySocialUserDetails; import org.springframework.beans.factory.annotation.Autowired; 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.SocialUserDetails; import org.springframework.social.security.SocialUserDetailsService; import org.springframework.stereotype.Service; @Service public class MySocialUserDetailsService implements SocialUserDetailsService { @Autowired private UserDetailsService userDetailService; // Tải thông tin người dùng đăng nhập bởi mạng xã hội. // (Phương thức này được sử dụng bởi Spring Social Security API) @Override public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException, DataAccessException { // Dựa trên UserDetailService. (Xem MyUserDetailService). UserDetails userDetails = userDetailService.loadUserByUsername(userId); return (MySocialUserDetails) userDetails; } }
7. Các lớp cho việc đăng ký tài khoản (SignUp)
Như đã giới thiệu ở phần trên. Sau khi đăng nhập thông qua mạng xã hội, nếu thông tin người dùng chưa tồn tại trên Dabase của ứng dụng, nó sẽ được tạo ra tự động hoặc chuyển hướng tới một trang cho phép người dùng nhập thông tin tài khoản.Trong trường hợp bạn muốn tự động tạo ra các bản ghi USER_ACCOUNTS & USERCONNECTION, bạn phải viết class thực hiện interface ConnectionSignUp.MyConnectionSignUp.javapackage org.o7planning.socialsecurity.signup; import org.o7planning.socialsecurity.dao.MyUserAccountDAO; import org.o7planning.socialsecurity.model.MyUserAccount; import org.springframework.social.connect.Connection; import org.springframework.social.connect.ConnectionSignUp; public class MyConnectionSignUp implements ConnectionSignUp { private MyUserAccountDAO myUserAccountDAO; public MyConnectionSignUp(MyUserAccountDAO myUserAccountDAO) { this.myUserAccountDAO = myUserAccountDAO; } // Sau khi đăng nhập mạng xã hội xong. // Phương thức này sẽ được gọi để tạo ra một bản ghi User_Account tương ứng // nếu nó chưa tồn tại. @Override public String execute(Connection<?> connection) { MyUserAccount account= myUserAccountDAO.createUserAccount(connection); return account.getId(); } }..MyUserAccountValidator.javapackage org.o7planning.socialsecurity.validator; import org.apache.commons.validator.routines.EmailValidator; import org.o7planning.socialsecurity.dao.MyUserAccountDAO; import org.o7planning.socialsecurity.form.MyUserAccountForm; import org.o7planning.socialsecurity.model.MyUserAccount; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; @Component public class MyUserAccountValidator implements Validator { // common-validator library. private EmailValidator emailValidator = EmailValidator.getInstance(); @Autowired private MyUserAccountDAO myUserAccountDAO; @Override public boolean supports(Class<?> clazz) { return clazz == MyUserAccountForm.class; } @Override public void validate(Object target, Errors errors) { MyUserAccountForm form = (MyUserAccountForm) target; ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email", "", "Email is required"); ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName", "", "User name is required"); ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "", "First name is required"); ValidationUtils.rejectIfEmptyOrWhitespace(errors, "lastName", "", "Last name is required"); ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "", "Password is required"); if (errors.hasErrors()) { return; } if (!emailValidator.isValid(form.getEmail())) { errors.rejectValue("email", "", "Email is not valid"); return; } MyUserAccount userAccount = myUserAccountDAO.findByUserName(form.getUserName()); if (userAccount != null) { if (form.getId() == null) { errors.rejectValue("userName", "", "User name is not available"); return; } else if (!form.getId().equals(userAccount.getId())) { errors.rejectValue("userName", "", "User name is not available"); return; } } userAccount = myUserAccountDAO.findByEmail(form.getEmail()); if (userAccount != null) { if (form.getId() == null) { errors.rejectValue("email", "", "Email is not available"); return; } else if (!form.getId().equals(userAccount.getId())) { errors.rejectValue("email", "", "Email is not available"); return; } } } }MyUserAccountForm.javapackage org.o7planning.socialsecurity.form; import org.springframework.social.connect.Connection; import org.springframework.social.connect.ConnectionKey; import org.springframework.social.connect.UserProfile; public class MyUserAccountForm { private String id; private String email; private String userName; private String firstName; private String lastName; private String password; private String role; private String signInProvider; private String providerUserId; public MyUserAccountForm() { } public MyUserAccountForm(Connection<?> connection) { UserProfile socialUserProfile = connection.fetchUserProfile(); this.id = null; this.email = socialUserProfile.getEmail(); this.userName = socialUserProfile.getUsername(); this.firstName = socialUserProfile.getFirstName(); this.lastName = socialUserProfile.getLastName(); ConnectionKey key = connection.getKey(); // google, facebook, twitter this.signInProvider = key.getProviderId(); // ID of User on google, facebook, twitter. // ID của User trên google, facebook, twitter. this.providerUserId = key.getProviderUserId(); } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } public String getSignInProvider() { return signInProvider; } public void setSignInProvider(String signInProvider) { this.signInProvider = signInProvider; } public String getProviderUserId() { return providerUserId; } public void setProviderUserId(String providerUserId) { this.providerUserId = providerUserId; } }SecurityUtil.javapackage org.o7planning.socialsecurity.util; import org.o7planning.socialsecurity.model.MyUserAccount; import org.o7planning.socialsecurity.user.MySocialUserDetails; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; public class SecurityUtil { // Tự động đăng nhập. public static void logInUser(MyUserAccount user) { MySocialUserDetails userDetails = new MySocialUserDetails(user); Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(authentication); } }8. Controller
MainController.javapackage org.o7planning.socialsecurity.controller; import org.o7planning.socialsecurity.dao.MyUserAccountDAO; import org.o7planning.socialsecurity.form.MyUserAccountForm; import org.o7planning.socialsecurity.model.MyUserAccount; import org.o7planning.socialsecurity.util.SecurityUtil; import org.o7planning.socialsecurity.validator.MyUserAccountValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.social.connect.Connection; import org.springframework.social.connect.ConnectionFactoryLocator; import org.springframework.social.connect.UsersConnectionRepository; import org.springframework.social.connect.web.ProviderSignInUtils; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @Controller // Cần thiết để sử dụng RedirectAttributes @EnableWebMvc public class MainController { @Autowired private MyUserAccountDAO myUserAccountDAO; @Autowired private ConnectionFactoryLocator connectionFactoryLocator; @Autowired private UsersConnectionRepository connectionRepository; @Autowired private MyUserAccountValidator myUserAccountValidator; // Set a form validator @InitBinder protected void initBinder(WebDataBinder dataBinder) { Object target = dataBinder.getTarget(); if (target == null) { return; } System.out.println("Target=" + target); if (target.getClass() == MyUserAccountForm.class) { dataBinder.setValidator(myUserAccountValidator); } } @RequestMapping(value = { "/" }, method = RequestMethod.GET) public String homePage(Model model) { try { UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication() .getPrincipal(); if (userDetails != null) { System.out.println(userDetails.getPassword()); System.out.println(userDetails.getUsername()); System.out.println(userDetails.isEnabled()); model.addAttribute("userDetails", userDetails); } } catch (Exception e) { } return "index"; } @RequestMapping(value = { "/login" }, method = RequestMethod.GET) public String welcomePage(Model model) { return "login"; } // Người dùng login bằng mạng xã hội, // nhưng không cho phép ứng dụng xem các thông tin cơ bản // ứng dụng sẽ chuyển hướng về trang /signin. @RequestMapping(value = { "/signin" }, method = RequestMethod.GET) public String signInPage(Model model) { return "redirect:/login"; } @RequestMapping(value = { "/signup" }, method = RequestMethod.GET) public String signupPage(WebRequest request, Model model) { ProviderSignInUtils providerSignInUtils // = new ProviderSignInUtils(connectionFactoryLocator, connectionRepository); // Nếu người dùng đăng nhập bằng mạng xã hội (Social), // Lấy ra thông tin mạng xã hội. Connection<?> connection = providerSignInUtils.getConnectionFromSession(request); // MyUserAccountForm myForm = null; // if (connection != null) { myForm = new MyUserAccountForm(connection); } else { myForm = new MyUserAccountForm(); } model.addAttribute("myForm", myForm); return "signup"; } @RequestMapping(value = { "/signup" }, method = RequestMethod.POST) public String signupSave(WebRequest request, // Model model, // @ModelAttribute("myForm") @Validated MyUserAccountForm accountForm, // BindingResult result, // final RedirectAttributes redirectAttributes) { // Nếu validate có lỗi. if (result.hasErrors()) { return "signup"; } MyUserAccount registered = null; try { registered = myUserAccountDAO.registerNewUserAccount(accountForm); } catch (Exception ex) { ex.printStackTrace(); model.addAttribute("errorMessage", "Error " + ex.getMessage()); return "signup"; } if (accountForm.getSignInProvider() != null) { ProviderSignInUtils providerSignInUtils // = new ProviderSignInUtils(connectionFactoryLocator, connectionRepository); // Nếu người dùng đăng nhập bởi mạng xã hội. Phương thức này // lưu thông tin mạng xã hội vào bảng UserConnection. providerSignInUtils.doPostSignUp(registered.getId(), request); } // Sau khi đăng ký xong, đăng nhập vào. SecurityUtil.logInUser(registered); return "redirect:/userInfo"; } @RequestMapping(value = { "/userInfo" }, method = RequestMethod.GET) public String userInfoPage(WebRequest request, Model model) { return "userInfo"; } }9. Các trang JSP
_menu.jsp<%@ taglib uri="http://www.springframework.org/security/tags" prefix="security"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <div style="padding: 5px; border: 1px solid #ccc;"> <a href="${pageContext.request.contextPath}/">Home</a> || <a href="${pageContext.request.contextPath}/userInfo">User Info</a> <security:authorize access="isAuthenticated()"> || <a href="${pageContext.request.contextPath}/logout">Logout</a> </security:authorize> <security:authorize access="!isAuthenticated()"> || <a href="${pageContext.request.contextPath}/login">Login</a> </security:authorize> <c:if test="${not empty pageContext.request.userPrincipal.name}"> || <span>Welcome : ${pageContext.request.userPrincipal.name}</span> <ul> <c:forEach items="${userDetails.authorities}" var="auth"> <li>${auth.authority }</li> </c:forEach> </ul> </c:if> </div>index.jsp<%@ taglib uri="http://www.springframework.org/security/tags" prefix="security"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> <meta charset="UTF-8"> <title>Home</title> </head> <body> <jsp:include page="_menu.jsp"/> <h2>Home Page</h2> <c:if test="${empty pageContext.request.userPrincipal.name}"> Click to 'User Info' to show user info (It will redirect to login page) </c:if> </body> </html>login.jsp<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> <meta charset="UTF-8"> <title>Login Page</title> </head> <body> <jsp:include page="_menu.jsp" /> <h2>Social Login</h2> <a href="${pageContext.request.contextPath}/auth/facebook">Face Book</a> <br /> <a href="${pageContext.request.contextPath}/auth/google">Google</a> <br /> <h2>Normal Login</h2> <c:if test="${param.error == 'true'}"> <div style="color:red;margin:10px 0px;"> Login Failed!!!<br /> Reason : ${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message} </div> </c:if> <form action="${pageContext.request.contextPath}/j_spring_security_check" method='POST'> <table> <tr> <td>User:</td> <td><input type='text' name='username' value=''></td> </tr> <tr> <td>Password:</td> <td><input type='password' name='password' /></td> </tr> <tr> <td><input name="submit" type="submit" value="submit" /></td> </tr> </table> </form> </body> </html>signup.jsp<!DOCTYPE html> <%@ page contentType="text/html;charset=UTF-8" language="java"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> <html> <head> <meta charset="UTF-8"> <title>Sign Up</title> <style> .error-message { font-size:90%; font-style:italic; color:red; } </style> </head> <body> <jsp:include page="_menu.jsp" /> <h1>Register</h1> <c:if test="${not empty myForm.signInProvider}"> <h2 style="color:blue;">Signup with ${myForm.signInProvider}</h2> </c:if> <form:form modelAttribute="myForm" method="POST"> <form:hidden path="id" /> <form:hidden path="signInProvider" /> <table border="0"> <tr> <td>User Name</td> <td><form:input path="userName" /></td> <td><form:errors path="userName" class="error-message" /></td> </tr> <tr> <td>Email</td> <td><form:input path="email" /></td> <td><form:errors path="email" class="error-message" /></td> </tr> <tr> <td>First Name</td> <td><form:input path="firstName" /></td> <td><form:errors path="firstName" class="error-message" /></td> </tr> <tr> <td>Last Name</td> <td><form:input path="lastName" /></td> <td><form:errors path="lastName" class="error-message" /></td> </tr> <tr> <td>Password</td> <td><form:input path="password" /></td> <td><form:errors path="password" class="error-message" /></td> </tr> <tr> <td></td> <td><input type="submit" value="Submit" /></td> <td></td> </tr> </table> </form:form> <div class="error-message">${errorMessage}</div> </body> </html>userInfo.jsp<%@ taglib uri="http://www.springframework.org/security/tags" prefix="security"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> <meta charset="UTF-8"> <title>User Info</title> </head> <body> <jsp:include page="_menu.jsp" /> <h1>User Info Page</h1> <h3>Welcome : ${pageContext.request.userPrincipal.name}</h3> <a href="${pageContext.request.contextPath}/logout">Logout</a> </body> </html>10. Chạy ứng dụng



Chú ý: Để test ứng dụng bạn có thể xóa hết các dữ liệu User trong Database, và xóa Cache của trình duyệt:Delete from User_Accounts; Delete From Userconnection;Tự động tạo tài khoản:Trường hợp bạn muốn khi người dùng đăng nhập thông qua mạng xã hội, các bản ghi USERCONNECTION & USER_ACCOUNTS được tạo ra một cách tự động. Bạn cần sửa lại class SocialConfig:** SocialConfig.java **@Configuration @EnableSocial // Load to Environment. @PropertySource("classpath:social-cfg.properties") public class SocialConfig implements SocialConfigurer { // ..... private boolean autoSignUp = true; ....... }
Hiển thị trang đăng kýTrường hợp, khi người dùng đăng nhập thông qua mạng xã hội, nếu chưa có bản ghi USERCONNECTION tương ứng, ứng dụng sẽ chuyển hướng tới trang đăng ký. Bạn cần sửa lại class SocialConfig:** SocialConfig.java **@Configuration @EnableSocial // Load to Environment. @PropertySource("classpath:social-cfg.properties") public class SocialConfig implements SocialConfigurer { // ..... private boolean autoSignUp = false; ....... }
Các hướng dẫn Spring MVC
- Hướng dẫn lập trình Spring cho người mới bắt đầu
- Cài đặt Spring Tool Suite cho Eclipse
- Hướng dẫn lập trình Spring MVC cho người mới bắt đầu - Hello Spring 4 MVC
- Cấu hình các nguồn dữ liệu tĩnh trong Spring MVC
- Hướng dẫn sử dụng Spring MVC Interceptor
- Tạo ứng dụng web đa ngôn ngữ với Spring MVC
- Hướng dẫn Upload File với Spring MVC
- Ứng dụng Java Web login đơn giản sử dụng Spring MVC, Spring Security và Spring JDBC
- Hướng dẫn sử dụng Spring MVC Security với Hibernate
- Hướng dẫn sử dụng Spring MVC Security và Spring JDBC (XML Config)
- Đăng nhập bằng mạng xã hội trong Spring MVC với Spring Social Security
- Hướng dẫn sử dụng Spring MVC và Velocity
- Hướng dẫn sử dụng Spring MVC với FreeMarker
- Sử dụng Template trong Spring MVC với Apache Tiles
- Hướng dẫn sử dụng Spring MVC và Spring JDBC Transaction
- Sử dụng nhiều DataSource trong Spring MVC
- Hướng dẫn sử dụng Spring MVC, Hibernate và Spring Transaction Manager
- Hướng dẫn sử dụng Spring MVC Form và Hibernate
- Chạy các nhiệm vụ nền theo lịch trình trong Spring
- Tạo một ứng dụng Java Web bán hàng sử dụng Spring MVC và Hibernate
- Ví dụ CRUD đơn giản với Spring MVC RESTful Web Service
- Triển khai ứng dụng Spring MVC trên Oracle WebLogic Server

Các hướng dẫn Spring MVC
- Hướng dẫn lập trình Spring cho người mới bắt đầu
- Cài đặt Spring Tool Suite cho Eclipse
- Hướng dẫn lập trình Spring MVC cho người mới bắt đầu - Hello Spring 4 MVC
- Cấu hình các nguồn dữ liệu tĩnh trong Spring MVC
- Hướng dẫn sử dụng Spring MVC Interceptor
- Tạo ứng dụng web đa ngôn ngữ với Spring MVC
- Hướng dẫn Upload File với Spring MVC
- Ứng dụng Java Web login đơn giản sử dụng Spring MVC, Spring Security và Spring JDBC
- Hướng dẫn sử dụng Spring MVC Security với Hibernate
- Hướng dẫn sử dụng Spring MVC Security và Spring JDBC (XML Config)
- Đăng nhập bằng mạng xã hội trong Spring MVC với Spring Social Security
- Hướng dẫn sử dụng Spring MVC và Velocity
- Hướng dẫn sử dụng Spring MVC với FreeMarker
- Sử dụng Template trong Spring MVC với Apache Tiles
- Hướng dẫn sử dụng Spring MVC và Spring JDBC Transaction
- Sử dụng nhiều DataSource trong Spring MVC
- Hướng dẫn sử dụng Spring MVC, Hibernate và Spring Transaction Manager
- Hướng dẫn sử dụng Spring MVC Form và Hibernate
- Chạy các nhiệm vụ nền theo lịch trình trong Spring
- Tạo một ứng dụng Java Web bán hàng sử dụng Spring MVC và Hibernate
- Ví dụ CRUD đơn giản với Spring MVC RESTful Web Service
- Triển khai ứng dụng Spring MVC trên Oracle WebLogic Server
Các bài viết mới nhất
- Dart Stream Single và Broadcast
- Xử lý lỗi trong Dart Stream
- Hướng dẫn và ví dụ Dart Stream
- So sánh đối tượng trong Dart với thư viện Equatable
- Flutter BloC cho người mới bắt đầu
- Xử lý lỗi 404 trong Flutter GetX
- Ví dụ đăng nhập và đăng xuất với Flutter Getx
- Hướng dẫn và ví dụ Flutter NumberTextInputFormatter
- Hướng dẫn và ví dụ Flutter multi_dropdown
- Hướng dẫn và ví dụ Flutter flutter_form_builder
- Hướng dẫn và ví dụ Flutter GetX obs Obx
- Hướng dẫn và ví dụ Flutter GetX GetBuilder
- Từ khoá part và part of trong Dart
- Hướng dẫn và ví dụ Flutter InkWell
- Hướng dẫn và ví dụ Flutter Radio
- Bài thực hành Flutter SharedPreferences
- Hướng dẫn và ví dụ Flutter Slider
- Hướng dẫn và ví dụ Flutter SkeletonLoader
- Chỉ định cổng cố định cho Flutter Web trên Android Studio
- Tạo Module trong Flutter
- Các hướng dẫn Spring MVC
Từ khóa » đăng Nhập Bằng Facebook Spring Boot
-
Login Với Facebook Trong Spring Boot
-
Code Ví Dụ Spring Boot Security Login Bằng Facebook - STACKJAVA
-
Code Ví Dụ Spring MVC Security, Login Bằng Facebook - STACKJAVA
-
Spring Boot Social Login With Facebook Example
-
Facebook Login Với Spring Social - Viblo
-
A Secondary Facebook Login With Spring Social - Baeldung
-
Spring Boot Login With Google And Facebook In One Application
-
Example Of OAuth2 Social Login In Spring Boot - O7planning
-
[Java] Spring Boot OAuth2 Đăng Nhập Social Network Với Google ...
-
Untitled
-
Spring Security Google Login
-
Custom Login Page Sử Dụng Bootstrap Và Thymeleaf Trong Spring ...
-
Lấy Thông Tin User Trong Spring Security - Laptrinhjavaweb
-
Cơ Chế đăng Nhập ứng Dụng Web, App Bằng Tài Khoản Google+/ ...
