Spring Security OAuth2 и анонимные пользователи

281
05 октября 2017, 11:29

Есть веб приложение на 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?

READ ALSO
Определять данные [требует правки]

Определять данные [требует правки]

У меня есть некоторая переменная data в которой складываются положительные и отрицателньые списки данных

329
Создался в Eclipse public class Snippet.

Создался в Eclipse public class Snippet.

В Eclipse неожиданно появился

277
Android java VpnService

Android java VpnService

ЗдравствуйтеПытаюсь написать клиент для VPN сервера

208