Spring Boot + Google OAuth2:如何定义用户详细信息服务?

问题描述:

我有简单的弹簧启动应用程序,我想在其中使用谷歌oauth2身份验证。它工作正常,但我不明白如何设置我自己的userDetailsS​​ervice为用户设置角色。Spring Boot + Google OAuth2:如何定义用户详细信息服务?

我的配置:

@SpringBootApplication 
@EnableWebMvc 
@EnableOAuth2Sso 
public class Application extends WebMvcAutoConfiguration { 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

...和application.properties:

security.oauth2.client.client-id: <client-d> 
security.oauth2.client.client-secret: <secret> 
security.oauth2.client.access-token-uri: https://www.googleapis.com/oauth2/v3/token 
security.oauth2.client.user-authorization-uri: https://accounts.google.com/o/oauth2/auth 
security.oauth2.client.client-authentication-scheme: form 
security.oauth2.client.scope: profile,email 
security.oauth2.resource.user-info-uri: https://www.googleapis.com/userinfo/v2/me 
security.oauth2.resource.prefer-token-info: false 

所以,我应该在哪里取悦我的UserDetailsS​​ervice的implemantation?只是将bean添加到上下文不起作用,它可能应该设置在某处,但是在哪里? 谢谢

我不知道这是否是解决这个问题的最佳方法,但它有效。 我已经添加了新的安全过滤器,用户权限正从数据库中检索。 应用类:

@Autowired 
private UserRepository userRepository; 

@Bean 
public FilterRegistrationBean filterRegistrationBean() { 
    FilterRegistrationBean registration = new FilterRegistrationBean(); 
    AuthoritiesFilter filter = new AuthoritiesFilter(); 
    filter.setUserRepository(userRepository); 
    registration.setFilter(filter); 
    registration.addUrlPatterns("/*"); 
    registration.setName("authoritiesFilter"); 
    registration.setOrder(Ordered.LOWEST_PRECEDENCE); 
    return registration; 
} 

当局过滤器:

public class AuthoritiesFilter extends GenericFilterBean { 
     public static final String EMAIL = "email"; 
     public static final String NAME = "name"; 
     public static final String GIVEN_NAME = "given_name"; 
     public static final String FAMILY_NAME = "family_name"; 
     public static final String PICTURE = "picture"; 
     public static final String GENDER = "gender"; 
     public static final String LOCALE = "locale"; 

     private UserRepository userRepository; 

     @Override 
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
      Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
      OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) authentication; 

      if (oAuth2Authentication != null && oAuth2Authentication.getUserAuthentication().getDetails() != null) { 
       SecurityContextHolder.getContext().setAuthentication(processAuthentication(authentication)); 
      } 

      chain.doFilter(request, response); 
     } 

     private OAuth2Authentication processAuthentication(Authentication authentication) { 
      OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) authentication; 
      Map<String, String> details = (Map<String, String>) oAuth2Authentication.getUserAuthentication().getDetails(); 

      User user = userRepository.getByEmail(details.get(EMAIL)) 
        .orElse(new User()); 
      updateUser(user, details); 
      userRepository.save(user); 

      UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
        oAuth2Authentication.getPrincipal(), 
        oAuth2Authentication.getCredentials(), 
        user.getAuthorities().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList())); 
      oAuth2Authentication = new OAuth2Authentication(oAuth2Authentication.getOAuth2Request(), token); 
      oAuth2Authentication.setDetails(details); 
      return oAuth2Authentication; 
     } 

     private void updateUser(User user, Map<String, String> details) { 
      user.setEmail(details.get(EMAIL)); 
      user.setName(details.get(NAME)); 
      user.setGivenName(details.get(GIVEN_NAME)); 
      user.setFamilyName(details.get(FAMILY_NAME)); 
      user.setPicture(details.get(PICTURE)); 
      user.setGender(details.get(GENDER)); 
      user.setLocale(details.get(LOCALE)); 
     } 

     public void setUserRepository(UserRepository userRepository) { 
      this.userRepository = userRepository; 
     } 
    }