Как правильно настроить Spring Security 5 OAuth с Vue. js? - PullRequest
0 голосов
/ 23 марта 2020

Мы создаем веб-приложение с Spring Boot и Vue. js. В настоящее время мы переходим с Security OAuth 2.x на Spring Security 5.2.x и испытываем проблемы с потоком Oauth2.

Ниже приведена конфигурация безопасности:

@EnableWebSecurity
@Configuration
@PropertySource("classpath:application.properties")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.headers().addHeaderWriter(new XFrameOptionsHeaderWriter(new StaticAllowFromStrategy(location)));

        http.authorizeRequests()
          .antMatchers("/login", "/static/**","/", "/actuator/prometheus")
          .permitAll()
          .anyRequest()
          .authenticated()
          .and()
          .oauth2Login();


    }

    private static List<String> clients = Arrays.asList("authnext");

    @Bean
    public ClientRegistrationRepository clientRegistrationRepository() {
        List<ClientRegistration> registrations = clients.stream()
          .map(c -> getRegistration(c))
          .filter(registration -> registration != null)
          .collect(Collectors.toList());

        return new InMemoryClientRegistrationRepository(registrations);
    }


    private ClientRegistration getRegistration(String client) {


        if (client.equals("authnext")) {

            return AuthNextOAuth2Provider.AUTHNEXT.getBuilder(client, "https://baseurl/auth/oauth2/realms/root/realms/intranetb2x/authorize",
                    "https://baseurl/auth/oauth2/realms/root/realms/intranetb2x/tokeninfo",
                    "https://baseurl/auth/oauth2/realms/root/realms/intranetb2x/userinfo")
                    .clientId("ID")
                    .clientSecret("SECRET")
                    .build();
        }

        return null;
    }

    @Bean
    public OAuth2AuthorizedClientService authorizedClientService() {

        return new InMemoryOAuth2AuthorizedClientService(
          clientRegistrationRepository());
    }

    @Bean
    public AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository() {

        return new HttpSessionOAuth2AuthorizationRequestRepository();
    }


}

Кроме того, у нас есть следующий AuthNextOAuth2Provider:

public enum AuthNextOAuth2Provider {

    AUTHNEXT {
        @Override
        public Builder getBuilder(String registrationId,String authUri,String tokenUri, String userInfoUri) {
            ClientRegistration.Builder builder = getBuilder(registrationId, ClientAuthenticationMethod.BASIC,DEFAULT_LOGIN_REDIRECT_URL);

            builder.scope("openid", "profile", "b2xroles");
            builder.authorizationUri(authUri);
            builder.tokenUri(tokenUri);
            builder.userInfoUri(userInfoUri);
            builder.userNameAttributeName(IdTokenClaimNames.SUB);
            builder.clientName("authnext");
            return builder;
        }
    };
    private static final String DEFAULT_LOGIN_REDIRECT_URL = "{baseUrl}/login";

    protected final ClientRegistration.Builder getBuilder(String registrationId, ClientAuthenticationMethod method,
            String redirectUri) {
        ClientRegistration.Builder builder = ClientRegistration.withRegistrationId(registrationId);
        builder.clientAuthenticationMethod(method);
        builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
        builder.redirectUriTemplate(redirectUri);
        return builder;
    }

    /**
     * Create a new
     * {@link org.springframework.security.oauth2.client.registration.ClientRegistration.Builder
     * ClientRegistration.Builder} pre-configured with provider defaults.
     * 
     * @param registrationId the registration-id used with the new builder
     * @return a builder instance
     */
    public abstract ClientRegistration.Builder getBuilder(
            String registrationId,
            String authUri,
            String tokenUri,
            String userInfoUri
    );

}

Проблема в том, что перенаправление работает неправильно. Мы можем быть правильно направлены на сервер авторизации и войти туда, но при перенаправлении обратно в приложение Spring мы получаем ошибку 404.

Как это работает, выглядит следующим образом. У нас есть приложение Spring Boot, которое находится в /. Я хочу разрешить все запросы к / / login und / static / **, чтобы ресурсы vue. js обслуживались правильно. Приложение vue. js вызывает состояние конечной точки бэкэнда, чтобы проверить, аутентифицирован ли в данный момент броузер. Если это не так, то пользователь перенаправляется на сервер аутентификации Oauth2 следующим образом:

 checkLoggedIn: function() {
  AXIOS({
    method: "GET",
    url: "/status",
    responseType: "blob"
  })
    .then(response => {

      var element = document.getElementById("step1");
      element.classList.add("step-active");
      document.getElementById("lock1").style.visibility = "hidden";
      document.getElementById("lock2").style.visibility = "hidden";
      document.getElementById("lock3").style.visibility = "visible";
      document.getElementById("lock4").style.visibility = "hidden";
      this.connect();

    })
    .catch(error => {

            if(typeof error.response === 'undefined'){
                var localStorage = window.localStorage;
                window.localStorage.setItem('route', JSON.stringify(this.$route));  
                window.location.href = "/login";
            }else if(error.response.status===403){
                 this.$parent.upload = false;
                 this.$parent.uploadResult = false;
                 this.$parent.checkData = false;
                 this.$parent.approveData = false;
                 this.$parent.checkout = false;
                 this.$parent.unauthorized=true; 

            }
    });
}},

Кажется, что принудительное посещение / вход в браузер запускает рабочий процесс аутентификации правильно, но на обратном пути есть проблема со следующим запросом:

Failed Redirect back to spring

Как правильно настроить поток входа в систему. Также кажется, что некоторые конечные точки создаются в бэкэнде формы:

oauth2 / authorization / authnext

Что это такое и нужно ли это. В Spring OAuth2 мы просто использовали @ EnableOauth2Sso и все работало.

Вот зависимости:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-jose</artifactId>
    </dependency>


    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>


    <!-- 
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
    </dependency>


    <dependency>
        <groupId>org.springframework.security.oauth.boot</groupId>
        <artifactId>spring-security-oauth2-autoconfigure</artifactId>
        <version>${oauth-auto.version}</version>
    </dependency>
    -->

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tika</groupId>
        <artifactId>tika-core</artifactId>
        <version>1.20</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.5</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-core</artifactId>
        <version>1.1.44</version>
    </dependency>


    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-ui</artifactId>
        <version>1.1.44</version>
    </dependency>

    <!-- <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-webflux-ui</artifactId> 
        <version>1.1.44</version> </dependency> <dependency> <groupId>org.springdoc</groupId> 
        <artifactId>springdoc-openapi-ui</artifactId> <version>1.1.44</version> </dependency> -->


    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
    </dependency>

    <dependency>
        <groupId>com.opencsv</groupId>
        <artifactId>opencsv</artifactId>
        <version>4.1</version>
    </dependency>

    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.5</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>


    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>





    <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-junit-jupiter</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.metrics</groupId>
        <artifactId>spring-metrics</artifactId>
        <version>0.5.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>io.prometheus</groupId>
        <artifactId>simpleclient_common</artifactId>
        <version>0.8.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
        <version>2.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
        <version>1.3.2</version>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-core</artifactId>
    </dependency>

</dependencies>
...