2

私はスプリングブートとスプリングセキュリティを使用しています。私の残りのコントローラでrest with accessTemplatebuiderのアクセス問題

、私は1つの方法別のスプリングブートアプリケーションで

@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] 

を取得私の主なアプリでは、私は春のセキュリティで見ることができるように、アプリケーションに接続するためにフォームのログインを使用しますconfig。

私の他のアプリから、フォームのログインなしで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); 

でWSを呼び出そうとしました:春のセキュリティのデフォルトのパスワードは、次のプロパティで構成されているhttp://pastebin.com/psNKPUtM

+0

私はこれがあなたの問題ではなく、様々な '@Enable ...'注釈しばしば「無効」春のブートのデフォルトを修正するかわからない...それは本当にです痛い...しかし、時にはそれらを必要とします。それらを削除してみてください。 また、テストクラスに注釈を表示でき、restTemplateがどのように設定されているかは... – xenoterracide

+0

私はEnableWebSecurityで試してみましたが、EnableGlobalAuthenticationとConfigurationが含まれていますが、同じ問題があります。 restTemplateの設定方法は既に示されています。私はテストクラスを持っていません。 –

+0

サーバアプリケーションがフォームログインを受け入れると、どのようにSpring起動クライアントで基本認証を使用できますか? – sura2k

答えて

1

security.user.password=YOUR_PASSWORD これはあなたが持っているあなたのメインアプリで行うべきですセキュリティの設定、および通話しようとしているあなたの承認を拒否しますcommerce.password春のパスワードと一致するプロパティを更新しなかった、あなたはデフォルトで401を取得する場合

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

だから、それはスタート時には、コンソールに出力しますいくつかのランダム生成されたパスワードを使用しています。 documentation

+0

commerce.usernameとそのパスワードはrestTemplateで使用されます。これらの情報は、システムにログするために使用されることを想定しており、春のセキュリティによって生成されるデフォルトのパスワードとは関係ありません。私のメインシステムにユーザーx、y zがある場合...私はシステムへの呼び出しを行うときにそれらを使用できると思います。 –

+0

さて、メインアプリで何が起きているのかは不明です。メインアプリケーションのTRACEロギングレベルをオンにして、リクエストを実行しようとしたときにログに記録される内容を確認してください。 –

+0

今、私は、デバッグし、org.springframework.security.access.intercept.AbstractSecurityInterceptor.authenticateIfRequired()まで歩くFilterSecurityInterceptorにブレークポイントを置くだろう 私はこれが何らかの理由であなたの匿名認証が返される場所だと思うあなたのヘッダーをチェックする。 また、認証= authenticationManager.authenticate(認証)にブレークポイントを設定しようとしました。 アプリケーションの再起動後に初めてリクエストを送信すると、そのヒットが発生することが予想されます。 –

1

formLogin()を設定していますが、RestTemplateでhttp Basic Authを使用しようとしています。 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. @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とする場合を使用して単純なクライアントを書く既存の設定にBASIC認証を追加します。 Java 8ではjava.util.Base64を使用できます。それ以外の場合は、commons-codecを使用してください。

更新: 春のブート参照: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どの春のセキュリティとスプリングブートのバージョンを実行していますか?どこかでカスタム認証フィルタがありますか? – sura2k

+0

とにかくnon-springの起動アプリケーションでは、formLogin()やhttpBasic()などの異なる設定の2つの別々のエンドポイント**を保護するために、@ Orderと2つの別々の '@Configuration'を使用する必要があります。両方をサポートしたいので、ここでは重要ではありません。 – sura2k

関連する問題