Ejecute una aplicación Spring Boot oAuth2 como servidor de recursos Y sirva contenido web

Estoy usando Spring Boot 1.5.13 y con Spring Security 4.2.6 y Spring Security oAuth2 2.0.15.

Quiero encontrar una configuración de mejores prácticas para nuestras aplicaciones Spring Boot que ofrecen un conjunto mixto de contenido: una API REST y algunas páginas web que brindan una "página de inicio" conveniente para los desarrolladores con algunos enlaces, además de API basada en Swagger documentación, que también es contenido web.

Tengo una configuración que me permite ejecutar la aplicación con el flujo de código de autorización adecuado, por lo tanto, puedo acceder a todo el contenido web a través del navegador y autenticarme con el IdP configurado (en mi caso, PingFederate), además puedo hacer llamadas API desde Navegador, es decir, directamente o con un cliente REST, p. Ej. con RESTClient.

Esta es mi configuración de seguridad:

@Slf4j
@Configuration
@EnableWebSecurity
@EnableOAuth2Sso // this annotation must stay here!
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login**", "/webjars/**", "/css/**").permitAll()
                .antMatchers("/cfhealth").permitAll()
                .antMatchers("/").permitAll()
                .antMatchers("/protected", "/api/**").authenticated();
    }

    @Bean
    public RequestContextListener requestContextListener() {
        return new RequestContextListener();
    }

}

y la configuración de oAuth2:

@Configuration
@Slf4j
public class OAuth2Config extends ResourceServerConfigurerAdapter {

    @Value("${pingfederate.pk-uri}")
    String pingFederatePublicKeyUri;

    @Autowired
    PingFederateKeyUtils pingFederateKeyUtils;

    @Override
    public void configure(ResourceServerSecurityConfigurer config) {
        config.tokenServices(tokenServices());
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        String certificate = pingFederateKeyUtils.getKeyFromServer(pingFederatePublicKeyUri);
        String publicKey = pingFederateKeyUtils.extractPublicKey(certificate);
        converter.setVerifier(pingFederateKeyUtils.createSignatureVerifier(publicKey));
        return converter;
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }

}

Pero cuando quiero llamar a una API REST programáticamente / fuera del navegador con un token de portador en el encabezado, p. con curl, el flujo del código de autorización se activa y redirige al punto final de inicio de sesión local. Lo que quiero es que las llamadas a la API acepten el token del portador para la autenticación, sin crear una sesión, y que todas las llamadas de contenido web / mvc en el navegador establezcan una sesión.

curl -i -H "Accept: application/json" -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8080/authdemo/api/hello

Agregando la anotación @EnableResourceServer a la clase SecurityConfig anterior (y agregando security.oauth2.resource.filter-order = 3 en el archivo de propiedades de la aplicación, puedo hacer que el comando curl funcione, pero luego el flujo del código de autorización está roto, obtengo la siguiente salida en el navegador para todas las URL de mi aplicación:

<oauth> <error_description> Full authentication is required to access this resource </error_description> <error>unauthorized</error> </oauth>

Ahora ¿hay alguna manera de hacer que este szenario funcione bien? Si es así, ¿cómo se vería eso? ¿O solo se admite en versiones posteriores de Spring Boot + Security + oAuth2?

La pregunta enSpring Boot con seguridad OAuth2: ¿cómo usar el servidor de recursos con el formulario de inicio de sesión web? es bastante similar

Respuestas a la pregunta(1)

Su respuesta a la pregunta