Есть веб приложение на Spring MVC, пытаюсь добавить к нему аутентификацию через Google. Настраиваю SpringSecurity следующим образом:
@Configuration
@EnableWebSecurity
@EnableOAuth2Client
@PropertySource("classpath:google-oauth2.properties")
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
OAuth2ClientContext oauth2ClientContext;
@Autowired
private OAuth2ClientContextFilter oauth2ClientContextFilter;
@Value("${oauth2.clientId}")
private String clientId;
@Value("${oauth2.clientSecret}")
private String clientSecret;
@Value("${oauth2.userAuthorizationUri}")
private String userAuthorizationUri;
@Value("${oauth2.accessTokenUri}")
private String accessTokenUri;
@Value("${oauth2.tokenName:authorization_code}")
private String tokenName;
@Value("${oauth2.scope}")
private String scope;
@Value("${oauth2.userInfoUri}")
private String userInfoUri;
@Value("${oauth2.filterCallbackPath}")
private String oauth2FilterCallbackPath;
@Bean
public AuthenticationEntryPoint authenticationEntryPoint() {
// May need an OAuth2AuthenticationEntryPoint for non-browser clients
return new LoginUrlAuthenticationEntryPoint(oauth2FilterCallbackPath);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/oauth2/**").permitAll()
.anyRequest().authenticated().and()
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint()).and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/").permitAll().and()
.addFilterBefore(ssoFilter(), FilterSecurityInterceptor.class)
.addFilterAfter(oauth2ClientContextFilter, ExceptionTranslationFilter.class)
.anonymous().disable();
}
@Bean
public Filter ssoFilter() {
OAuth2ClientAuthenticationProcessingFilter facebookFilter = new OAuth2ClientAuthenticationProcessingFilter(oauth2FilterCallbackPath);
OAuth2RestTemplate facebookTemplate = new OAuth2RestTemplate(facebook(), oauth2ClientContext);
GoogleUserInfoTokenServices tokenServices = new GoogleUserInfoTokenServices(userInfoUri, clientId);
facebookFilter.setRestTemplate(facebookTemplate);
facebookFilter.setTokenServices(tokenServices);
return facebookFilter; }
@Bean
public OAuth2ProtectedResourceDetails facebook() {
AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
details.setId("google-oauth-client");
details.setClientId(clientId);
details.setClientSecret(clientSecret);
details.setUserAuthorizationUri(userAuthorizationUri);
details.setAccessTokenUri(accessTokenUri);
details.setTokenName(tokenName);
String commaSeparatedScopes = scope;
details.setScope(parseScopes(commaSeparatedScopes));
details.setAuthenticationScheme(AuthenticationScheme.query);
details.setClientAuthenticationScheme(AuthenticationScheme.form);
return details;
}
private List<String> parseScopes(String commaSeparatedScopes) {
List<String> scopes = new LinkedList<>();
Collections.addAll(scopes, commaSeparatedScopes.split(","));
return scopes;
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/css/**", "/js/**", "/pages/**");
}
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return new NoopAuthenticationManager();
}
private static class NoopAuthenticationManager implements AuthenticationManager {
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
throw new UnsupportedOperationException(
"No authentication should be done with this AuthenticationManager");
}
}
@Bean
@Description("Enables ${...} expressions in the @Value annotations"
+ " on fields of this configuration. Not needed if one is"
+ " already available.")
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Авторизация через google работает отлично, но из за отключенного анонимного доступа пользователи не могут зайти даже на главную страницу без авторизации. Если включить анонимный доступ, перестает работать OAuth с ошибкой:
Authentication Failed: Authentication is required to obtain an access token (anonymous not allowed)
Единственное нормальное описание проблемы нашел на форуме Spring
Но я не могу понять 1 момента. В моем сценарии пользователи до авторизации ходят по сайту под анонимной учеткой, а после авторизации через OAuth получают свой профиль и ходят уже под ним. Соответсвтенно, авторизация через OAuth нужна для того что бы сопоставить учетку Google с локальным пользователем и получить часть данных из профиля Google. В варианте описанном на форуме сказано, что до авторизации через OAuth необходимо дать пользователю не анонимную учетку для идентификации пользователя.
Подскажите пожалуйста, как реализовать такой механизм аутентификации. Может я в корне не понимаю предназначение OAuth?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
У меня есть некоторая переменная data в которой складываются положительные и отрицателньые списки данных