2

私は、フォームログインとGoogle OAuth2ログインという2つのログインメカニズムをサポートするSpring SecurityでSpring Bootアプリケーションを設定することを渋滞しています。フォームログインとGoogle OAuth2ログインの両方をサポートするようにSpring BootとSpring Securityを設定する方法

伝統的なログインフォームのログインページが必要です。このページには、「Googleで認証する」ボタンもあります。

ログインフォームは、デフォルトのログイン方法です。つまり、login.jspがレンダリングする保護されたリソースにアクセスしようとするときです。ここで、ユーザはoauthボタンをクリックすることができます。

重要な点は、ログインやGoogleの認証のどちらか一方を個別に設定できることですが、それらを連携させることはできません。

1.-フォームログイン:

@EnableWebSecurity 
class SecurityConfig extends WebSecurityConfigurerAdapter{ 

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

2.-、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")) 
    } 
} 

答えて

1

これは私が2 WebSecurityConfigurerAdapter Sを使用して、それを解決する方法である:

@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() 
     } 
    } 
} 

フルソースコードは以下にあります。https://github.com/codependent/spring-boot-google-signin

関連する問題