Comment configurer Spring Boot et Spring Security pour prendre en charge la connexion par formulaire et la connexion Google OAuth2

codépendant

J'ai du mal à configurer une application Spring Boot avec Spring Security pour prendre en charge deux mécanismes de connexion: la connexion par formulaire et la connexion Google OAuth2.

Je souhaite avoir une page de connexion avec le formulaire de connexion traditionnel. Cette page aurait également un bouton "Authentifier avec Google".

Le formulaire de connexion serait la méthode de connexion par défaut, c'est-à-dire que lors d'une tentative d'accès à une ressource protégée, le login.jsp serait rendu. Ici, l'utilisateur peut cliquer sur le bouton oauth.

Le fait est que je peux les configurer séparément, que ce soit par connexion par formulaire ou par authentification Google, mais je ne suis pas en mesure de les faire fonctionner ensemble.

1.- Connexion par formulaire:

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
        .and()
            .formLogin()

2.- Authentification Google:

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter{

    private final String LOGIN_URL = "/login"

    @Autowired
    OAuth2ClientContextFilter oAuth2ClientContextFilter

    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return new LoginUrlAuthenticationEntryPoint(LOGIN_URL)
    }

    @Bean
    public OpenIDConnectAuthenticationFilter openIdConnectAuthenticationFilter(){
        return new OpenIDConnectAuthenticationFilter(LOGIN_URL)
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterAfter(oAuth2ClientContextFilter, AbstractPreAuthenticatedProcessingFilter.class)
            .addFilterAfter(openIdConnectAuthenticationFilter(), OAuth2ClientContextFilter.class)
            .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
        .and()
            .authorizeRequests()
                .anyRequest.authenticated()
    }
}


class OpenIDConnectAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    @Resource
    private OAuth2RestOperations restTemplate

    protected OpenIDConnectAuthenticationFilter(String defaultFilterProcessesUrl) {
        super(defaultFilterProcessesUrl)
        setAuthenticationManager({authentication -> authentication}) // AbstractAuthenticationProcessingFilter requires an authentication manager.
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {
        final ResponseEntity<UserInfo> userInfoResponseEntity = restTemplate.getForEntity("https://www.googleapis.com/oauth2/v2/userinfo", UserInfo.class)
        new PreAuthenticatedAuthenticationToken(userInfoResponseEntity.getBody(), empty(), NO_AUTHORITIES)
    }
}

class UserInfo {
    final String id
    final String name
    final String givenName
    final String familyName
    final String gender
    final String picture
    final String link

    @JsonCreator
    public UserInfo(@JsonProperty("id") String id,
                    @JsonProperty("name") String name,
                    @JsonProperty("given_name") String givenName,
                    @JsonProperty("family_name") String familyName,
                    @JsonProperty("gender") String gender,
                    @JsonProperty("picture") String picture,
                    @JsonProperty("link") String link) {
        this.id = id
        this.name = name
        this.givenName = givenName
        this.familyName = familyName
        this.gender = gender
        this.picture = picture
        this.link = link
    }

}

@Configuration
@EnableOAuth2Client
class OAuth2Client {

    @Value('${google.oauth2.clientId}')
    private String clientId

    @Value('${google.oauth2.clientSecret}')
    private String clientSecret

    @Bean
    // TODO retrieve from https://accounts.google.com/.well-known/openid-configuration ?
    public OAuth2ProtectedResourceDetails googleOAuth2Details() {
        AuthorizationCodeResourceDetails googleOAuth2Details = new AuthorizationCodeResourceDetails()
        googleOAuth2Details.setAuthenticationScheme(form)
        googleOAuth2Details.setClientAuthenticationScheme(form)
        googleOAuth2Details.setClientId(clientId)
        googleOAuth2Details.setClientSecret(clientSecret)
        googleOAuth2Details.setUserAuthorizationUri("https://accounts.google.com/o/oauth2/auth")
        googleOAuth2Details.setAccessTokenUri("https://www.googleapis.com/oauth2/v3/token")
        googleOAuth2Details.setScope(asList("openid"))
        googleOAuth2Details
    }

    @Resource
    private OAuth2ClientContext oAuth2ClientContext

    @Bean
    @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
    public OAuth2RestOperations googleOAuth2RestTemplate() {
        new OAuth2RestTemplate(googleOAuth2Details(), oAuth2ClientContext)
    }
}

class CustomUserDetailsService implements AuthenticationUserDetailsService<OpenIDAuthenticationToken> {

    UserDetails loadUserDetails(OpenIDAuthenticationToken token) throws UsernameNotFoundException {
        new User(token.name, "", AuthorityUtils.createAuthorityList("ROLE_USER"))
    }
}
codépendant

Voici comment je l'ai résolu en utilisant deux WebSecurityConfigurerAdapters:

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Configuration
    @Order(1)
    static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher("/secure-home")
                .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .permitAll()
        }
    }

    @Configuration
    @Order(2)
    static class OAuth2SecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        private final String LOGIN_URL = "/googleLogin";

        @Autowired
        OAuth2ClientContextFilter oAuth2ClientContextFilter

        @Bean
        AuthenticationEntryPoint authenticationEntryPoint() {
            new LoginUrlAuthenticationEntryPoint(LOGIN_URL)
        }

        @Bean
        OpenIDConnectAuthenticationFilter openIdConnectAuthenticationFilter() {
            new OpenIDConnectAuthenticationFilter(LOGIN_URL)
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .addFilterAfter(oAuth2ClientContextFilter, AbstractPreAuthenticatedProcessingFilter.class)
                .addFilterAfter(openIdConnectAuthenticationFilter(), OAuth2ClientContextFilter.class)
            .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
            .and()
                .authorizeRequests()
                    .antMatchers(GET, "/googleOAuth2").authenticated()
        }
    }
}

Le code source complet est disponible ici: https://github.com/codependent/spring-boot-google-signin

Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.

En cas d'infraction, veuillez [email protected] Supprimer.

modifier le
0

laisse moi dire quelques mots

0commentaires
connexionAprès avoir participé à la revue

Articles connexes

Formulaire de connexion personnalisé. Configurer la sécurité Spring pour obtenir une réponse JSON

Comment configurer l'expérience et la génération d'un nouveau jeton d'accès pour la connexion avec Spring Boot et OAuth2.0

Spring Security OAuth2: Comment fournir deux liens de connexion séparés pour deux types d'utilisateurs?

Authentification de base Spring Security et connexion par formulaire pour la même API

Comment utiliser Spring Security pour personnaliser la page de connexion?

Comment fonctionne la redirection de connexion Spring Oauth2?

Angular 2, Spring Boot, Spring Security, formulaire de connexion

spring boot oauth2.0 et spring security: comment accorder l'autorisation (autorités) à la connexion de l'utilisateur via facebook ou slack

Spring Boot et Spring Security sont toujours redirigés vers la connexion

spring security échec de la première connexion et succès de la deuxième connexion

Spring Security pour valider la connexion RestAPI

Comment configurer la connexion dans Spring-Boot pour la fonction de couleur ANSI?

Spring Security Oauth2 et configuration de la connexion par formulaire

Spring Boot avec Security OAuth2 - Comment utiliser le serveur de ressources avec le formulaire de connexion Web?

Spring Boot Security avec authentification à 3 champs et formulaire de connexion personnalisé

Comment avoir des sources d'authentification distinctes? (un pour Oauth2 et un pour la connexion par formulaire)

comment configurer les informations d'identification pour la connexion à l'application google et la connexion à gmail

Spring Boot 2 Security télécharge le fichier de police lors de la connexion

Autorisation incrémentielle pour la connexion à Google OAuth2 avec Spring Security

Comment prendre en charge la connexion Apple avec AWS Cognito?

Spring Security et connexion Angularjs

Comment modifier Directadmin.inc.php pour prendre en charge la connexion SSL

Comment configurer l'application Spring Boot pour prendre en charge l'encodage UTF-8 et GBK?

Comment configurer la connexion OAuth2 sous Android ?

Comment configurer la page de connexion dans Spring Boot 2 avec WebFlux ?

Connexion Spring security oauth2 et serveur de ressources dans la même application

La déconnexion ne fonctionne pas avec Spring Boot, Spring Security et Thymleaf

Comment obtenir l'utilisateur de la base de données pour la connexion avec Spring Boot et Spring Data Jpa

Comment configurer la page de connexion de démarrage Spring tout en sécurisant l'API REST à l'aide de la connexion sociale OAuth2

TOP liste

chaudétiquette

Archive