简体   繁体   中英

Spring Boot + Google OAuth2: how to define user details service?

I have simple spring boot application and I wnat to use google oauth2 authentication in it. It works fine, but I don't understand how to set my own userDetailsService to set roles for users.

My config:

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

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

...and 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

So, where should I please my implemantation of UserDetailsService? Just adding the bean to the context doesn't work, it probably should set somewhere, but where? Thanks

I don't know if it is the best way to do solve this, but it works. I have added new security filter, where user authorities are being retrieved from database. Application class:

@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;
}

Authorities filter:

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;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM