Spring Boot + Google OAuth2:如何定义用户详细信息服务?
问题描述:
我有简单的弹簧启动应用程序,我想在其中使用谷歌oauth2身份验证。它工作正常,但我不明白如何设置我自己的userDetailsService为用户设置角色。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
所以,我应该在哪里取悦我的UserDetailsService的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;
}
}