7

मैंने स्प्रिंग बूट (1.5.2), स्प्रिंग सिक्योरिटी और स्प्रिंग सिक्योरिटी ओएथ 2 का उपयोग करके Google+ एपीआई के साथ ओएथ 2 लॉगिन को लागू करने के लिए एक छोटी परियोजना स्थापित की है। https://github.com/ccoloradoc/OAuth2Sampleस्प्रिंग बूट + स्प्रिंग सिक्योरिटी + स्प्रिंग ओएथ 2 + Google साइन इन

मैं गूगल के साथ प्रमाणित और उपयोगकर्ता जानकारी बाहर खींच करने में सक्षम हूँ:

आप स्रोत में पा सकते हैं। हालांकि, लॉगआउट के बाद मैं फिर से लॉगिन नहीं कर सकता क्योंकि मुझे "400 खराब अनुरोध" मिला है, जब मैं अपने एपीटी को Google एपीआई का आह्वान करने के लिए "https://accounts.google.com/o/oauth2/auth" कनेक्ट करने का प्रयास करता हूं।

फ़िल्टर प्रयास देखें आगे संदर्भ के लिए प्रमाणीकरण विधि।

यहाँ मेरी सुरक्षा विन्यास वर्ग है

@Configuration 
@EnableGlobalAuthentication 
@EnableOAuth2Client 
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) 
@PropertySource(value = {"classpath:oauth.properties"}) 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 


    @Autowired 
    private UserDetailsService userDetailsService; 

    @Resource 
    @Qualifier("accessTokenRequest") 
    private AccessTokenRequest accessTokenRequest; 

    @Autowired 
    private OAuth2ClientContextFilter oAuth2ClientContextFilter; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     // @formatter:off 
     http. 
       authorizeRequests() 
       .antMatchers(HttpMethod.GET, "/login","/public/**", "/resources/**","/resources/public/**").permitAll() 
       .antMatchers("/google_oauth2_login").anonymous() 
       .anyRequest().authenticated() 
       .and() 
       .formLogin() 
       .loginPage("/login") 
       .loginProcessingUrl("/login") 
       .defaultSuccessUrl("/") 
       .and() 
       .csrf().disable() 
       .logout() 
       .logoutSuccessUrl("/") 
       .logoutUrl("/logout") 
       .deleteCookies("remember-me") 
       .and() 
       .rememberMe() 
       .and() 
       .addFilterAfter(oAuth2ClientContextFilter,ExceptionTranslationFilter.class) 
       .addFilterAfter(googleOAuth2Filter(),OAuth2ClientContextFilter.class) 
       .userDetailsService(userDetailsService); 
     // @formatter:on 
    } 

    @Bean 
    @ConfigurationProperties("google.client") 
    public OAuth2ProtectedResourceDetails auth2ProtectedResourceDetails() { 
     return new AuthorizationCodeResourceDetails(); 
    } 

    @Bean 
    public OAuth2RestTemplate oauth2RestTemplate() { 
     return new OAuth2RestTemplate(auth2ProtectedResourceDetails(), 
       new DefaultOAuth2ClientContext(accessTokenRequest)); 
    } 


    @Bean 
    public GoogleOAuth2Filter googleOAuth2Filter() { 
     return new GoogleOAuth2Filter("/google_oauth2_login"); 
    } 

    /* 
    * Building our custom Google Provider 
    * */ 
    @Bean 
    public GoogleOauth2AuthProvider googleOauth2AuthProvider() { 
     return new GoogleOauth2AuthProvider(); 
    } 

    /* 
    * Using autowired to assign it to the auth manager 
    * */ 
    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) { 
     auth.authenticationProvider(googleOauth2AuthProvider()); 
    } 

    @Bean 
    public SpringSecurityDialect springSecurityDialect() { 
     return new SpringSecurityDialect(); 
    } 

    @Bean 
    public TokenStore tokenStore() { 
     return new InMemoryTokenStore(); 
    } 

} 

यहाँ मेरी प्रमाणीकरण प्रदाता है:

public class GoogleOauth2AuthProvider implements AuthenticationProvider { 

    private static final Logger logger = LoggerFactory.getLogger(GoogleOauth2AuthProvider.class); 

    @Autowired(required = true) 
    private UserDetailsService userDetailsService; 

    @Override 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
     logger.info("Provider Manager Executed"); 
     CustomOAuth2AuthenticationToken token = (CustomOAuth2AuthenticationToken) authentication; 
     UserDetailsImpl registeredUser = (UserDetailsImpl) token.getPrincipal(); 
     try { 
      registeredUser = (UserDetailsImpl) userDetailsService 
        .loadUserByUsername(registeredUser.getEmail()); 
     } catch (UsernameNotFoundException usernameNotFoundException) { 
      logger.info("User trying google/login not already a registered user. Register Him !!"); 
     } 
     return token; 
    } 

    @Override 
    public boolean supports(Class<?> authentication) { 
     return CustomOAuth2AuthenticationToken.class 
       .isAssignableFrom(authentication); 
    } 
} 

UserDetailService वसंत सुरक्षा कोर से एक कार्यान्वयन है कि डेटाबेस से उपयोगकर्ता पढ़ता है और एक UserDetails POJO इसका अनुवाद है जो वसंत सुरक्षा कोर उपयोगकर्ता विवरण लागू करता है।

public class GoogleOAuth2Filter extends AbstractAuthenticationProcessingFilter { 

    /** 
    * Logger 
    */ 
    private static final Logger log = LoggerFactory.getLogger(GoogleOAuth2Filter.class); 

    private static final Authentication dummyAuthentication; 

    static { 
     dummyAuthentication = new UsernamePasswordAuthenticationToken(
       "dummyUserName23452346789", "dummyPassword54245", 
       CustomUserDetails.DEFAULT_ROLES); 
    } 

    private static final String NAME = "name"; 
    private static final String EMAIL = "email"; 
    private static final String PICTURE = "picture"; 

    private static final Logger logger = LoggerFactory 
      .getLogger(GoogleOAuth2Filter.class); 


    @Value(value = "${google.authorization.url}") 
    private String googleAuhorizationUrl; 

    public GoogleOAuth2Filter(String defaultFilterProcessesUrl) { 
     super(defaultFilterProcessesUrl); 
    } 

    @Autowired 
    private UserService userService; 

    @Autowired 
    private OAuth2RestTemplate oauth2RestTemplate; 

    @Autowired 
    @Override 
    public void setAuthenticationManager(AuthenticationManager authenticationManager) { 
     super.setAuthenticationManager(authenticationManager); 
    } 

    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, 
               HttpServletResponse response) throws AuthenticationException, 
      IOException, ServletException { 
     logger.info("Google Oauth Filter Triggered!!"); 
     URI authURI; 
     try { 
      authURI = new URI(googleAuhorizationUrl); 
     } catch (URISyntaxException e) { 
      log.error("\n\n\n\nERROR WHILE CREATING GOOGLE AUTH URL", e); 
      return null; 
     } 
     SecurityContext context = SecurityContextHolder.getContext(); 
     // auth null or not authenticated. 
     String code = request.getParameter("code"); 
     Map<String, String[]> parameterMap = request.getParameterMap(); 
     logger.debug(parameterMap.toString()); 
     if (StringUtils.isEmpty(code)) { 
      // Google authentication in progress. will return null. 
      logger.debug("Will set dummy user in context "); 
      context.setAuthentication(dummyAuthentication); 
      // trigger google oauth2. 
      // ERROR ON SECOND LOGIN ATTEMPT 
      oauth2RestTemplate.postForEntity(authURI, null, Object.class); 
      return null; 
     } else { 
      logger.debug("Response from Google Recieved !!"); 

      ResponseEntity<Object> forEntity = oauth2RestTemplate.getForEntity(
        "https://www.googleapis.com/plus/v1/people/me/openIdConnect", 
        Object.class); 

      @SuppressWarnings("unchecked") 
      Map<String, String> profile = (Map<String, String>) forEntity.getBody(); 

      CustomOAuth2AuthenticationToken authenticationToken = getOAuth2Token(
        profile.get(EMAIL), profile.get(NAME), profile.get(PICTURE)); 
      authenticationToken.setAuthenticated(false); 

      return getAuthenticationManager().authenticate(authenticationToken); 
     } 
    } 

    private CustomOAuth2AuthenticationToken getOAuth2Token(
      String email, String name, String picture) { 

     User user = userService.findByEmail(email); 
     //Register user 
     if(user == null) { 
      user = new User(name, email, picture); 
      userService.saveOrUpdate(user); 
     } 

     UserDetailsImpl registeredUser = new UserDetailsImpl(name, email, picture); 

     CustomOAuth2AuthenticationToken authenticationToken = 
       new CustomOAuth2AuthenticationToken(registeredUser); 

     return authenticationToken; 
    } 

} 

उत्तर

3

चीजें अगर आप EnableOAuth2Sso विधि का उपयोग (हालांकि यह आप से प्रक्रिया का एक बहुत छुपाता है) बहुत आसान मिलती है:

यहाँ मेरी फिल्टर कार्यान्वयन है। The Spring Boot tutorial on OAuth2 इसके लिए काफी गहन है, और ऑनलाइन अन्य उदाहरण हैं जिन्हें मैंने (जैसे https://github.com/SoatGroup/spring-boot-google-auth/ और http://dreamix.eu/blog/java/configuring-google-as-oauth2-authorization-provider-in-spring-boot) से थोड़ा सा मदद की है। आखिरकार, this was the resource जिसने मुझे पूरी प्रक्रिया और एकीकरण क्लाइंट साइड ऐप को कवर करने में सबसे ज्यादा मदद की।

यदि आप इसे निम्न स्तर पर करना चाहते हैं, तो पूरी प्रक्रिया के बारे में बहुत सारी जानकारी है और यह Pivotal blog post पर वसंत में कैसे काम करता है।

संबंधित मुद्दे