Мы создаем веб-приложение с 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;
}
});
}},
Кажется, что принудительное посещение / вход в браузер запускает рабочий процесс аутентификации правильно, но на обратном пути есть проблема со следующим запросом:
Как правильно настроить поток входа в систему. Также кажется, что некоторые конечные точки создаются в бэкэнде формы:
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>