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



我有一个简单的弹簧启动应用程序,我想在其中使用谷歌oauth2身份验证。它工作正常,但我不明白如何设置我自己的用户详细信息服务来为用户设置角色。

我的配置:

@SpringBootApplication
@EnableWebMvc
@EnableOAuth2Sso
public class Application extends WebMvcAutoConfiguration {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

。和应用程序属性:

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

那么,我应该在哪里取悦我对用户详细信息服务的质疑?仅将 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;
        }
    }

最新更新