2017-10-23 4 views
5

私はモバイル/ Webアプリケーションで消費されるSpring Cloud Dalston.SR4を使用してマイクロサービスアーキテクチャのバックエンドAPIサーバーを実装しようとしています。Spring Cloud Zuul - 生成されたjwtトークンを使用すると認証サーバーからアクセスが拒否されました

APIゲートウェイ以下

はゲートウェイマイクロサービスの構成である

@SpringBootApplication 
@EnableEurekaClient 
@EnableZuulProxy 
public class ApiGatewayApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(ApiGatewayApplication.class, args); 
    } 

} 
@Configuration 
@EnableWebSecurity 
@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER) 
@EnableOAuth2Sso 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.csrf().disable() // 
       .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 
       .and().authorizeRequests() // 
       .antMatchers("/login", "/uaa/**").permitAll() // 
       .anyRequest().authenticated(); 
    } 

} 

application.yml

zuul: 
    ignoredServices: '*' 
    routes: 
    user-service: 
     path: /users/** 
     service-id: user-service 
     sensitive-headers: 
    uaa: 
     path: /uaa/** 
     strip-prefix: false 
     url: ${auth-server.uri}/ 
     sensitive-headers: 
security: 
    user: 
    password: none 
    basic: 
    enabled: false 
    oauth2: 
    client: 
     client-id: client 
     client-secret: secret 
     scope: openid 
     access-token-uri: ${auth-server.uri}/uaa/oauth/token 
     user-authorization-uri: ${auth-server.uri}/uaa/oauth/authorize 
    resource: 
     jwt: 
     key-value: | 
      -----BEGIN PUBLIC KEY----- 
      MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhVny3DfQqdvQaPj6SJiiFfPRGH/5k3OiAXTCsmpKnL/GVKZpfFjT3LhN7xoj0DzJLTCOE94eOjIHipFzxrL00kBCZJ3HOornKDpTh17yPuqJI6DNmvJaRBbc3SVQsO0vndnDAeOBiv4euGHH97sPZYFqhmwM35PboqxeWaHrfgWcA5F8VFTp+HDPr26G4sv/UqkR1LsfRoD4gzNJswi00eWcNjeoEzy71023VECQYDytUg/wVqWOJnShWOJnCBnuzmjrtOCg6O6ecdHhVaiRI0//ZR71x2oDW5pe+kgVhhM29TH8SVRjbAFh35obN6ppcF3A7PFLf+euZTsmXMaahQIDAQAB 
      -----END PUBLIC KEY----- 

認証-サービス

@SpringBootApplication 
@RestController 
@EnableEurekaClient 
@EnableResourceServer 
public class AuthServiceApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(AuthServiceApplication.class, args); 
    } 

    @GetMapping("/user") 
    public Principal getUser(Principal user) { 
     return user; 
    } 

} 
@Configuration 
@EnableAuthorizationServer 
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter { 

    @Autowired 
    private AuthenticationManager authenticationManager; 

    @Bean 
    public JwtAccessTokenConverter jwtAccessTokenConverter() { 
     KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), "keypass".toCharArray()); 
     JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); 
     converter.setKeyPair(keyStoreKeyFactory.getKeyPair("keystore")); 
     return converter; 
    } 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.inMemory() // 
       .withClient("client") // 
       .secret("secret") // 
       .authorizedGrantTypes("authorization_code", "refresh_token", "password") // 
       .scopes("openid") // 
       .accessTokenValiditySeconds(60 * 60 * 24 * 1); 
    } 

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
     endpoints.authenticationManager(authenticationManager).accessTokenConverter(jwtAccessTokenConverter()); 
    } 

    @Override 
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { 
     oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()"); 
    } 

} 
@Configuration 
@Order(-20) 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.formLogin().disable()// 
       .csrf().disable() // 
       .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access") // 
       .and().authorizeRequests().anyRequest().authenticated(); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.inMemoryAuthentication().withUser("user1").password("pass1").roles("USER"); 
    } 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

} 

この設定では、uaa/oauth/tokenサービスからアクセストークンを生成できます。そして私はuaa/userサービスのエンドポイントを呼び出すために同じトークンを使用することができ、他のマイクロサービス(user-service)を直接呼び出している間でさえも使用できます。

しかし、以前に生成されたトークンを使用してゲートウェイ経由でユーザーサービスを呼び出すと、認証サーバーからのアクセス拒否エラーが発生します。

要求 - ヘッダ認証をhttp://localhost:8080/users/test

を:ベアラ>

<

しかし、認証サーバーからの応答が、アクセスがEnableOAuth2Sso @

2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.security.web.FilterChainProxy  : /oauth/authorize?client_id=client&redirect_uri=http://localhost:8080/login&response_type=code&scope=openid&state=6AYJ3I at position 5 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.s.w.s.DefaultSavedRequest   : pathInfo: both null (property equals) 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.s.w.s.DefaultSavedRequest   : queryString: arg1=client_id=client&redirect_uri=http://localhost:8080/login&response_type=code&scope=openid&state=GwhNJf; arg2=client_id=client&redirect_uri=http://localhost:8080/login&response_type=code&scope=openid&state=6AYJ3I (property not equals) 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.s.w.s.HttpSessionRequestCache  : saved request doesn't match 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.security.web.FilterChainProxy  : /oauth/authorize?client_id=client&redirect_uri=http://localhost:8080/login&response_type=code&scope=openid&state=6AYJ3I at position 6 of 10 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.security.web.FilterChainProxy  : /oauth/authorize?client_id=client&redirect_uri=http://localhost:8080/login&response_type=code&scope=openid&state=6AYJ3I at position 7 of 10 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.sprin[email protected]905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 0F2BD608483668F10E9AD88B507858E9; Granted Authorities: ROLE_ANONYMOUS' 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.security.web.FilterChainProxy  : /oauth/authorize?client_id=client&redirect_uri=http://localhost:8080/login&response_type=code&scope=openid&state=6AYJ3I at position 8 of 10 in additional filter chain; firing Filter: 'SessionManagementFilter' 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.security.web.FilterChainProxy  : /oauth/authorize?client_id=client&redirect_uri=http://localhost:8080/login&response_type=code&scope=openid&state=6AYJ3I at position 9 of 10 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.security.web.FilterChainProxy  : /oauth/authorize?client_id=client&redirect_uri=http://localhost:8080/login&response_type=code&scope=openid&state=6AYJ3I at position 10 of 10 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /oauth/authorize?client_id=client&redirect_uri=http://localhost:8080/login&response_type=code&scope=openid&state=6AYJ3I; Attributes: [authenticated] 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.sprin[email protected]905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 0F2BD608483668F10E9AD88B507858E9; Granted Authorities: ROLE_ANONYMOUS 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] o.s.s.access.vote.AffirmativeBased  : Voter: org.sp[email protected]21c53585, returned: -1 
2017-10-23 12:38:41.470 DEBUG 4320 --- [trace=,span=] [nio-9999-exec-4] 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) 
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) 

答えて

3

を拒否されたがSSOを持つすべてのゲートウェイのURLを保護します。下流のマイクロサービスにつながるルートで認証を無効にして、ベアラトークンがそれらに到達できるようにする必要があると思います。

ゲートウェイ上であなたpermitAll()マッチャーに/users/**を追加してみてください:

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.csrf().disable() 
     .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
     .and().authorizeRequests() 
     .antMatchers("https://stackoverflow.com/users/**", /login", "/uaa/**").permitAll(); 
} 
関連する問題