Как объединить Spring Boot Security OAuth2 и базовую аутентификацию - PullRequest
0 голосов
/ 30 сентября 2019

в нашем проекте мы используем аутентификацию oauth2, если пользователь вызывает API с токеном носителя.

Если пользователь вызывает API с базовой аутентификацией, я могу добавить второй securityConfig для базовой аутентификации. Но как я могу аутентифицировать этого пользователя basicAuth с провайдером oauth2?

Я пытался с customAuthenticationProvider получить токен доступа с restTemplate, это работает.

Есть ли другое решение?

Это мой SecurityConfig:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        @Value("${security.oauth2.resource.id}")
        private String resourceId;

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources.resourceId(resourceId);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                    .authorizeRequests()
                    .antMatchers(HttpMethod.OPTIONS, "/api/**").permitAll()
                    .antMatchers("/api/**").authenticated();
        }
    }

    @Order(2)
    @Configuration
    protected static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

        private final RestTemplateBuilder restTemplateBuilder;

        @Value("${oauth2.issuer}")
        private String issuer;

        @Autowired
        public WebSecurityConfiguration(RestTemplateBuilder restTemplateBuilder) {
            this.restTemplateBuilder = restTemplateBuilder;
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.anonymous().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                    .requestMatcher(new BasicRequestMatcher())
                    .authorizeRequests()
                    .antMatchers(HttpMethod.OPTIONS, "/api/**").permitAll()
                    .antMatchers("/api/**").authenticated()
                    .and()
                    .httpBasic();
        }

        private static class BasicRequestMatcher implements RequestMatcher {
            @Override
            public boolean matches(HttpServletRequest request) {
                String auth = request.getHeader("Authorization");
                return (auth != null && auth.startsWith("Basic"));
            }
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(new OauthAuthenticationProvider(restTemplateBuilder, issuer));
        }
    }
}

Это пользователь CustomAuthenticationProvider

@Slf4j
public class OauthAuthenticationProvider implements AuthenticationProvider {

    private final RestTemplateBuilder restTemplateBuilder;
    private String issuer;

    OauthAuthenticationProvider(RestTemplateBuilder restTemplateBuilder, String issuer) {
        this.restTemplateBuilder = restTemplateBuilder;
        this.issuer = issuer;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> authorizationParameters = new LinkedMultiValueMap<>();
        authorizationParameters.add("username", authentication.getPrincipal().toString());
        authorizationParameters.add("password", authentication.getCredentials().toString());
        authorizationParameters.add("client_id", "client-id");
        authorizationParameters.add("client_secret", "client-secret");
        authorizationParameters.add("grant_type", "password");

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(authorizationParameters, headers);
        final RestTemplate restTemplate = restTemplateBuilder.rootUri(issuer).build();

        try {

            final ResponseEntity<DefaultOAuth2AccessToken> tokenResponseEntity = restTemplate.postForEntity("/protocol/openid-connect/token", request, DefaultOAuth2AccessToken.class, Collections.emptyMap());
            if (tokenResponseEntity.getBody() != null) {
                return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), "N/A", Collections.emptyList());
            }
        } catch (HttpClientErrorException e) {
            log.info(e.getMessage(), e);
            throw e;
        }

        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...