diff --git a/clearing-parent/backend-api/pom.xml b/clearing-parent/backend-api/pom.xml index 138531400..b66387ac0 100644 --- a/clearing-parent/backend-api/pom.xml +++ b/clearing-parent/backend-api/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 backend-api - Clearing Frontend API - Clearing frontend API module - war + Clearing Backend API + Clearing backend API module + jar clearing-parent @@ -55,8 +55,13 @@ + true + true ru.spcex.clearing.backendapi.BackendApiApplication + + Maven + @@ -82,6 +87,26 @@ + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + + + + ${project.artifactId} + + \ No newline at end of file diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/config/RestTemplateConfig.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/config/RestTemplateConfig.java new file mode 100644 index 000000000..5ca0bb367 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/config/RestTemplateConfig.java @@ -0,0 +1,30 @@ +package ru.spcex.clearing.backendapi.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +import java.time.Duration; + +@Configuration +public class RestTemplateConfig { + private final RestTemplateBuilder builder; + + @Autowired + public RestTemplateConfig(RestTemplateBuilder builder) { + this.builder = builder; + } + + /** + * В настоящий момент используется для выгрузки AFS данных + */ + @Bean("clearing-rest") + public RestTemplate restTemplate() { + return builder + .setConnectTimeout(Duration.ofMillis(10000)) + .setReadTimeout(Duration.ofMillis(40000)) + .build(); + } +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/LoginController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/LoginController.java new file mode 100644 index 000000000..bc5405967 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/LoginController.java @@ -0,0 +1,48 @@ +package ru.spcex.clearing.backendapi.controller; + +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.client.RestTemplate; +import ru.spcex.clearing.backendapi.security.TokenRequest; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +@Controller +@RequestMapping("/backend-api-login") +public class LoginController { + private final RestTemplate restTemplate; + + @Autowired + public LoginController(@Qualifier("clearing-rest") RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + @RequestMapping(value = "/perform-login", method = RequestMethod.POST) + public ResponseEntity> refreshToken(HttpServletRequest httpServletRequest, + HttpServletResponse httpServletResponse) { + RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) httpServletRequest.getSession().getAttribute(KeycloakSecurityContext.class.getName()); + String login = httpServletRequest.getHeader("clearing-login"); + String password = httpServletRequest.getHeader("clearing-password"); + HttpEntity> request = + new TokenRequest.Builder() + .username(login) + .password(password) + .build(); + ResponseEntity response = restTemplate.postForEntity( + "http://10.200.200.147:8080/realms/master/protocol/openid-connect/token", + request, String.class); + return null; + + } + +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/SimpleUserDetailService.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/SimpleUserDetailService.java new file mode 100644 index 000000000..484a15861 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/SimpleUserDetailService.java @@ -0,0 +1,15 @@ +package ru.spcex.clearing.backendapi.security; + +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Component; + +@Component +public class SimpleUserDetailService +// implements UserDetailsService +{ +// @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + return null; + } +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/TokenRequest.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/TokenRequest.java new file mode 100644 index 000000000..dea835816 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/TokenRequest.java @@ -0,0 +1,38 @@ +package ru.spcex.clearing.backendapi.security; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.Collections; + +public class TokenRequest { + public static class Builder{ + MultiValueMap data; + public Builder(){ + data = new LinkedMultiValueMap<>(); + data.put("client_id", Collections.singletonList("clearing")); + data.put("grant_type", Collections.singletonList("password")); + data.put("client_secret", Collections.singletonList("WnOVCxcAmrUYc8IjiFHOuRif5Oesoyfr")); + } + + + public Builder username(String username){ + data.put("username", Collections.singletonList(username)); + return this; + } + public Builder password(String password){ + data.put("password", Collections.singletonList(password)); + return this; + } + public HttpEntity> build(){ + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + return new HttpEntity<>(data, headers); + } + } + private TokenRequest(){ + } +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/WebSecurityConfig.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/WebSecurityConfig.java index 6d7f19ddc..3726994ea 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/WebSecurityConfig.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/WebSecurityConfig.java @@ -44,10 +44,15 @@ public class WebSecurityConfig extends KeycloakWebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { super.configure(http); http +// .formLogin() +// .loginProcessingUrl("/backend-api-login/perform-login") +// .and() + .csrf().disable() .authorizeRequests() .antMatchers("/anonymous/**").permitAll() .antMatchers("/sso/login").permitAll() .antMatchers("/error").permitAll() + .antMatchers("/backend-api-login/**").permitAll() .anyRequest().hasAnyRole("admin"); } } diff --git a/clearing-parent/backend-api/src/main/resources/keycloak.json b/clearing-parent/backend-api/src/main/resources/keycloak.json index b298527cc..9bf0d2e54 100644 --- a/clearing-parent/backend-api/src/main/resources/keycloak.json +++ b/clearing-parent/backend-api/src/main/resources/keycloak.json @@ -8,7 +8,7 @@ "cors-max-age" : 1000, "cors-allowed-methods" : "POST, PUT, DELETE, GET", "cors-exposed-headers" : "WWW-Authenticate, My-custom-exposed-Header", - "bearer-only" : false, + "bearer-only" : true, "enable-basic-auth" : false, "expose-token" : false, "verify-token-audience" : true,