Spring boot OAuth2Client, пользователь не аутентифицирован после обратного вызова: SecurityContext пуст или содержимое анонимно - PullRequest
0 голосов
/ 10 октября 2019

Я настраиваю приложение Spring Boot, которое будет аутентифицировать пользователя с помощью OAuth2 и OpenID Connect. Для реализации, я следую за ссылкой здесь: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2

После того, как код авторизации сделан, пользователь не аутентифицирован. Как аутентифицировать пользователя?

Серверу OpenID, на который я полагаюсь, требуется дополнительный параметр для конечной точки авторизации (acr_values ​​= {value}).

Я могу добавить параметр, используяAuthorizationRequestResolver и вызвать конечную точку авторизации, затем сервер перенаправляет меня на мой обратный вызов, но пользователь не аутентифицирован. Из трассировки SecurityContext пуст и не сохраняется в httpsession. Я вижу в журналах, что запрос POST к конечной точке токена отправляется, и я получаю ответ 200.

MySecurityConfig


test

package com.uta.security.edc.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest;
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import com.uta.security.edc.oauth2.MyAuthorizationRequestResolver;
import com.uta.security.edc.oauth2.MyTokenResponseConverter;

@Configuration
@EnableOAuth2Client
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private ClientRegistrationRepository clientRegistrationRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/", "/connect/**", "/test/**", "/assets/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .oauth2Login()
                .loginPage("/connect/login")
                .authorizationEndpoint()
                    .baseUri("/connect/authorization")
                    .authorizationRequestResolver(this.authorizationRequestResolver())
                    .and()
                .redirectionEndpoint()
                    .baseUri("/connect/callback")
                    .and()
                .tokenEndpoint()
                    .accessTokenResponseClient(this.accessTokenResponseClient())
                    .and()
                .userInfoEndpoint()
                    .and()
                .defaultSuccessUrl("/")
                .failureUrl("/connect/loginFailure")
                .and()
            .oauth2Client();
    }

    @Bean 
    public MyAuthorizationRequestResolver authorizationRequestResolver()
    {
        return new MyAuthorizationRequestResolver(this.clientRegistrationRepository);
    }

    @Bean
    public OAuth2RestTemplate oauth2RestTemplate()
    {
        return new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(new DefaultAccessTokenRequest()));
    }

    @Bean
    protected OAuth2ProtectedResourceDetails resource() {
        ClientRegistration clientRegistration = clientRegistrationRepository.findByRegistrationId("my-connect");
        AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
        List<String> scopes = new ArrayList<String>(1);
        scopes.add("uta-poc-edc");
        resource.setAccessTokenUri(clientRegistration.getProviderDetails().getTokenUri());
        resource.setClientId(clientRegistration.getClientId());
        resource.setClientSecret(clientRegistration.getClientSecret());
        resource.setScope(scopes);
        return resource;
    }

    @Bean
    public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient()
    {        
        DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient(); 

        OAuth2AccessTokenResponseHttpMessageConverter tokenResponseHttpMessageConverter = new OAuth2AccessTokenResponseHttpMessageConverter(); 
        tokenResponseHttpMessageConverter.setTokenResponseConverter(new MyTokenResponseConverter()); 

        RestTemplate restTemplate = this.oauth2RestTemplate();
        //RestTemplate restTemplate = new RestTemplate(Arrays.asList(new FormHttpMessageConverter(), tokenResponseHttpMessageConverter)); 
        restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler()); 
        accessTokenResponseClient.setRestOperations(restTemplate); 

        return accessTokenResponseClient;
    }

    /*@Bean
    public OAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository)
    {
        OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
                        .authorizationCode()
                        .refreshToken()
                        .build();

        DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);
        authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

        return authorizedClientManager;
    }*/
}

, а также MyClientApplication

package com.uta.security.edc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextListener;

@SpringBootApplication
public class myClientApplication extends SpringBootServletInitializer
{
    public static void main(String[] args) 
    {
        SpringApplication.run(myClientApplication.class, args);
    }

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

Мне нужно, чтобы пользователь прошел аутентификацию и его данные аутентификации были сохранены в его httpsession для запроса серверов ресурсов.

Спасибо за вашу помощь!

...