2

Я использую весенний ботинок и весеннюю безопасность.Доступ к проблеме с restTemplatebuider

В моем контроллере покоя, у меня есть один метод

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled=true) 
@EnableWebSecurity 
public class ApplicationSecurity extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private RESTAuthenticationEntryPoint authenticationEntryPoint; 

    @Autowired 
    private RESTAuthenticationFailureHandler authenticationFailureHandler; 

    @Autowired 
    private RESTAuthenticationSuccessHandler authenticationSuccessHandler; 

    @Autowired 
    private UserDetailsService userDetailsService; 

    @Bean 
    public PasswordEncoder encoder() { 
     return new BCryptPasswordEncoder(); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userDetailsService).passwordEncoder(encoder()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

     http.authorizeRequests() 
       .antMatchers("/login").permitAll() 
       .antMatchers("/rest/**").authenticated(); 

     http.csrf().disable(); 
     http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint); 

     http.formLogin().successHandler(authenticationSuccessHandler); 
     http.formLogin().failureHandler(authenticationFailureHandler); 
     http.logout().logoutUrl("/logout"); 
     http.logout().logoutSuccessUrl("/"); 

     // CSRF tokens handling 
     //http.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class); 
    } 

} 

@RequestMapping(value = "/rest") 
@RestController 
public class MemberController { 

    @GetMapping(value = "/members/card") 
    public boolean hasCardIdValid(@RequestBody String cardId) { 
     return memberService.hasCardIdValid(cardId); 
    } 
} 

В другом приложении весны загрузки, я пытаюсь вызвать метод hasCreditCard

@Autowired 
    public GlobalScan(RestTemplateBuilder restTemplateBuilder, @Value("${main.server.url}") String mainServerUrl, @Value("${commerce.username}") String commerceUsername, @Value("${commerce.password}")String commercePassword) { 
     this.restTemplate = restTemplateBuilder.basicAuthorization(commerceUsername, commercePassword).rootUri(mainServerUrl).build(); 
    } 

I do a call with this code 

Map<String, String> vars = new HashMap<String, String>(); 
vars.put("cardId", cardId); 

boolean accessAllowed = restTemplate.getForObject("/rest/members/card/" , Boolean.class, vars); 

я получаю это сообщение

2016-11-02 16:20:50.601 DEBUG 7139 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/rest/members/card/'; against '/login' 
2016-11-02 16:20:50.601 DEBUG 7139 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/rest/members/card/'; against '/rest/**' 
2016-11-02 16:20:50.601 DEBUG 7139 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /rest/members/card/; Attributes: [authenticated] 
2016-11-02 16:20:50.601 DEBUG 7139 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.sprin[email protected]9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS 
2016-11-02 16:20:50.602 DEBUG 7139 --- [nio-8080-exec-1] o.s.s.access.vote.AffirmativeBased  : Voter: org.sp[email protected]3d300693, returned: -1 
2016-11-02 16:20:50.602 TRACE 7139 --- [nio-8080-exec-1] ationConfigEmbeddedWebApplicationContext : Publishing event in org.springframework.boot[email protected]2bdd8394: org.springframework.security.access.event.AuthorizationFailureEvent[source=FilterInvocation: URL: /rest/members/card/] 
2016-11-02 16:20:50.606 DEBUG 7139 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter  : Access is denied (user is anonymous); redirecting to authentication entry point 

org.springframework.security.access.AccessDeniedException: Access is denied 
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-4.1.1.RELEASE.jar:4.1.1.RELEASE] 

В моем основном приложении я использую логин формы для подключения к приложению, как вы можете видеть в весенней безопасности конфигурации.

Из моего другого приложения, как назвать ws без формы логин?

попытался вызвать WS с этим

final RequestConfig config = RequestConfig.custom().setConnectTimeout(timeout * 1000).setConnectionRequestTimeout(timeout * 1000).setSocketTimeout(timeout * 1000).build(); 

final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 
credentialsProvider.setCredentials(new AuthScope("http://localhost", 8080, AuthScope.ANY_REALM), new UsernamePasswordCredentials("bob", "smith")); 
final CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(config).setDefaultCredentialsProvider(credentialsProvider).build(); 

final ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(client); 
RestTemplate restTemplate = new RestTemplate(requestFactory); 

ResponseEntity<MemberDto> member = restTemplate.getForEntity("http://localhost:8080/rest/members/1", MemberDto.class); 

результат: http://pastebin.com/psNKPUtM

+0

Я не уверен, что это будет исправить вашу проблему, но различное '' @Enable ... аннотации часто «отключить» загрузку по умолчанию пружинной ... это действительно болезненные ... но иногда они вам нужны. Попробуйте удалить их. Также, если вы можете показать аннотации на вашем тестовом классе и как настроен restTemplate ... – xenoterracide

+0

Я пробовал только с EnableWebSecurity, но включал EnableGlobalAuthentication и Configuration, но получал такую ​​же проблему. как уже настроен restTemplate. У меня нет тестового класса. –

+0

Как вы можете использовать базовую аутентификацию в клиенте Spring Boot, когда серверное приложение принимает форму входа? – sura2k

ответ

1

пароль по умолчанию в весеннем безопасности настраивается следующим свойством: security.user.password=YOUR_PASSWORD Это должно быть сделано в главном приложении, где у вас есть настройки безопасности и которые вы пытаетесь вызвать.

You can change the password by providing a security.user.password. This and other useful properties are externalized via SecurityProperties (properties prefix "security").

Так что, если вы не обновить свойство, чтобы соответствовать пароль в commerce.password весной отклонит ваше разрешение, и вы получите 401. По умолчанию он использует некоторые случайные сгенерированный пароль, если он выводит на консоль во время запуска , documentation

+0

имя пользователя commerce.us и его пароль используются в restTemplate. информация тезисов предполагается использовать для входа в систему, ничего общего с паролем по умолчанию, созданным весной безопасности. Если в моей основной системе есть пользователь x, y z ... я предполагаю, что смогу использовать их, когда я звоню в систему. –

+0

Хорошо, тогда неясно, что происходит в главном приложении. Можете ли вы включить уровень ведения журнала TRACE для своего основного приложения и проверить, что он регистрирует, когда вы пытаетесь выполнить запрос. –

+0

Теперь я бы поместил точку останова в FilterSecurityInterceptor, чтобы отлаживать и проходить до org.springframework.security.access.intercept.AbstractSecurityInterceptor.authenticateIfRequired() Я думаю, что именно по какой-то причине ваша анонимная аутентификация возвращается проверки заголовков. Также попробуйте поставить точку останова при аутентификации = authenticationManager.authenticate (authentication); Я ожидаю, что он будет ударить с первого раза, когда вы отправите запрос после перезапуска приложения. –

1

Вы настраиваете formLogin(), но вы пытаетесь использовать HTTP Basic Auth в своем RestTemplate. Для запросов через HTTP REST Я предлагаю вам изменить конфигурацию, чтобы использовать базовую авторизацию:

@Override 
protected void configure(HttpSecurity http) throws Exception { 

    http.authorizeRequests() 
      .antMatchers("/login").permitAll() 
      .antMatchers("/rest/**").authenticated(); 

    http.csrf().disable(); 
    http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint); 

    http.httpBasic(); 
    http.logout().logoutUrl("/logout"); 
    http.logout().logoutSuccessUrl("/"); 

    // CSRF tokens handling 
    //http.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class); 
} 

Если вам нужно как я думаю, что вы можете настроить оба.

+0

не удалось вызвать ws, ошибка: http://pastebin.com/psNKPUtM –

0
  1. Добавить BASIC AUTH к существующей конфигурации

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
        http 
         .... 
        .and() 
        .formLogin() // <------ Keep this 
         .... 
        .and() 
        .httpBasic() // <------ Add BASIC Auth 
        .and() 
         .....; 
    } 
    
  2. Написать простой клиент, используя RestTemplate

    public static void main(String[] args) { 
        RestTemplate rest = new RestTemplate(new ArrayList(Arrays.asList(new MappingJackson2HttpMessageConverter()))); 
        HttpHeaders headers = new HttpHeaders(); 
        headers.set("Authorization", "Basic YOUR_BASE64_ENCODED_CREDENTIALS"); 
        MediaType applicationJson = new MediaType("application","json"); 
        headers.setContentType(applicationJson); 
        headers.setAccept(Collections.singletonList(applicationJson)); 
        ResponseEntity<YourResponseObject> resp = rest.exchange("http://URL/rest/yourendpoint", HttpMethod.GET, new HttpEntity<String>("parameters", headers), YourResponseObject.class); 
    
        System.out.println(resp.getBody()); 
    

    }

YOUR_BASE64_ENCODED_CREDENTIALS => Если использовать U se Java 8 вы можете использовать java.util.Base64, иначе используйте commons-codec, чтобы сделать это или что-то еще.

Update: Spring загрузка ссылка: http://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html#jc-httpsecurity

+0

попытался использовать и то и другое, но войти в систему заблокирован, чтобы работать ... похоже, что пароль не работает ... необходимо отправить заголовок с авторизацией в противном случае это не сработает ... –

+0

Я только что протестировал то, что я предложил здесь. Это сработало. Также ознакомьтесь с документами Spring Boot. Похоже, что это автоконфигурация по умолчанию: http://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html#jc-httpsecurity. Какую весеннюю версию безопасности и весеннюю версию вы используете? У вас есть пользовательские auth-фильтры? – sura2k

+0

В любом случае в приложениях, не связанных с весной, вы должны использовать две отдельные '@ Configuration' с' @ Order' для защиты ** двух отдельных конечных точек ** с различными конфигурациями, такими как formLogin() и httpBasic(), но это не важно здесь, так как вы хотите поддержать оба. – sura2k