Il s'agit d'un mémo lorsque la fonction de connexion SNS est implémentée dans l'application Web créée par Spring Boot.
Java 8 (désolé) Spring Boot 2.1.0.RELEASE
https://projects.spring.io/spring-social/ https://spring.io/blog/2018/07/03/spring-social-end-of-life-announcement
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-oauth2-client
①POM
pom.xml
<!-- OAuth2 authentication-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
②configuration
SecurityConfig
//Seule la partie liée à la connexion est extraite.
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@NonNull
SaveAndGenerateUserDetails saveAndGenerateUserDetails
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//Connexion SNS
.oauth2Login()
.loginPage("/login")
.userInfoEndpoint()
//Classe de service à exécuter lors de l'authentification OAuth
.userService(new OAuth2UserService(saveAndGenerateUserDetails))
//Classe de service à exécuter lors de l'authentification OpenId
.oidcUserService(new OidcUserDetailsService(saveAndGenerateUserDetails))
.and()
//Implémentez SuccessHandler si nécessaire
.successHandler(new MyAuthenticationSuccessHandler())
//Implémentez SuccessHandler si nécessaire. Cette fois est la valeur par défaut.
.failureHandler(new SimpleUrlAuthenticationFailureHandler("/login?error"))
.and()
//La connexion ID PASS peut coexister
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.successHandler(new FormLoginSuccessHandler())
.failureHandler(new SimpleUrlAuthenticationFailureHandler("/login?error"))
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll()
.and()
.exceptionHandling();
}
③application.yml
application.yml
spring:
security:
oauth2:
client:
registration:
facebook:
client-id: 【client-id】
client-secret: 【client-secret】
scope:
- email
- public_profile
redirect-uri:[URL de l'application]/login/oauth2/code/{registrationId}
google:
client-id: 【client-id】
client-secret: 【client-secret】
scope:
- email
- profile
- openid
redirect-uri:[URL de l'application]/login/oauth2/code/{registrationId}
provider:
facebook:
authorizationUri: https://www.facebook.com/v3.3/dialog/oauth
tokenUri: https://graph.facebook.com/v3.3/oauth/access_token
userInfoUri: https://graph.facebook.com/v3.3/me
④view
login.html
<!--Créez un lien qui définit le point de terminaison de chaque connexion SNS.
Les points de terminaison sont des valeurs fixes et sont les suivants.-->
<!--~ Diverses omissions ~-->
<a href="/oauth2/authorization/facebook">Identifiant Facebook</a>
<a href="/oauth2/authorization/google">Connexion Google</a>
<!--~ Diverses omissions ~-->
⑤Service ⑤-1 classe OAuth (définie dans .userService () de SecurityConfig)
OAuth2UserService.java
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OAuth2UserService
extends DefaultOAuth2UserService {
@NonNull
SaveAndGenerateUserDetails saveAndGenerateUserDetails
@Override
@Transactional(readOnly = false)
public OAuth2User loadUser(OAuth2UserRequest userRequest)
throws OAuth2AuthenticationException {
//L'introduction de la classe d'implémentation est omise.
//Contour:
//Créez une classe pour chaque SNS à créer une branche avec registrationId et récupérez les informations que vous souhaitez acquérir.
//Enregistrer les informations utilisateur dans la base de données en fonction des informations acquises
//Informations d'authentification basées sur les informations acquises(UserDetails)Sera retourné.
//Le type de retour de cette classe diffère selon la méthode d'authentification, mais le type de retour de la méthode de processus est MyUserDetails.
//Nous allons donc ici absorber la différence de méthode d'authentification.
return saveAndGenerateUserDetails.process(userRequest,
super.loadUser(userRequest));
}
}
⑤-2 Traitement après l'authentification OpenId (défini dans .oidcUserService () de SecurityConfig)
OidcUserDetailsService.java
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OidcUserDetailsService
extends OidcUserService {
@NonNull
SaveAndGenerateUserDetails saveAndGenerateUserDetails;
@Override
@Transactional(readOnly = false)
public OidcUser loadUser(OidcUserRequest userRequest)
throws OAuth2AuthenticationException {
// ⑤-Identique à 1
return saveAndGenerateUserDetails.process(userRequest,
super.loadUser(userRequest));
}
}
⑥ Classe MyUserDetails
MyUserDetails.java
@SuppressWarnings("serial")
@Data
public class MyUserDetails implements UserDetails, OAuth2User, OidcUser {
// @Quelle méthode doit être remplacée?
//Seule la partie nécessaire à la connexion SNS est extraite.
private Map<String, Object> attributes;
//constructeur
public MyUserDetails(MyUser user, Map<String, Object> attr) {
//Seules les informations OAuth et OpenId sont répertoriées.
this.attributes = attr;
}
}
・ Il y avait moins de cours à préparer par moi-même que ce à quoi je m'attendais. ・ Il est utile que la bibliothèque fasse quelque chose de bien, mais c'était une boîte noire. ・ Si vous implémentez un type d'oauth et un type d'openid, vous pouvez facilement étendre horizontalement.
Recommended Posts