2016-10-24 11 views
0

私はOAuth2を初めてSpringブートAPIに実装しています。Spring Boot OAuth、JwtTokenStoreクラスでヌルポインタ例外を取得する

私はAPIからアクセストークンを取得することができましたが、APIを使用して呼び出しを行うと、次のエラーが発生します。

java.lang.NullPointerException: null 
    at org.springframework.security.oauth2.provider.token.store.JwtTokenStore.convertAccessToken(JwtTokenStore.java:92) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 
    at org.springframework.security.oauth2.provider.token.store.JwtTokenStore.readAccessToken(JwtTokenStore.java:84) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 
    at org.springframework.security.oauth2.provider.token.DefaultTokenServices.loadAuthentication(DefaultTokenServices.java:229) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 
    at org.springframework.security.oauth2.provider.token.DefaultTokenServices$$FastClassBySpringCGLIB$$5a1f25c.invoke(<generated>) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:651) ~[spring-aop-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.security.oauth2.provider.token.DefaultTokenServices$$EnhancerBySpringCGLIB$$ad6a1bf8.loadAuthentication(<generated>) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 
    at org.springframework.security.oauth2.provider.token.DefaultTokenServices$$FastClassBySpringCGLIB$$5a1f25c.invoke(<generated>) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:651) ~[spring-aop-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.security.oauth2.provider.token.DefaultTokenServices$$EnhancerBySpringCGLIB$$dd6c66fe.loadAuthentication(<generated>) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager.authenticate(OAuth2AuthenticationManager.java:83) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:150) ~[spring-security-oauth2-2.0.10.RELEASE.jar:na] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) ~[spring-security-web-4.1.1.RELEASE.jar:4.1.1.RELEASE] 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:522) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1110) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_25] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_25] 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.4.jar:8.5.4] 
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25] 

これはAPIへのリクエストです。

GET /api/test HTTP/1.1 
Host: localhost:8090 
Authorization: Bearer MYTOKENHERE 
Cache-Control: no-cache 

これはOAuthServerを構成するクラスです。

@Configuration パブリッククラスOAuth2ServerConfiguration {

private static final String RESOURCE_ID = "myapi"; 

@Configuration 
@EnableResourceServer 
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 
    @Autowired 
    private JwtAccessTokenConverter jwtAccessTokenConverter; 

    @Override 
    public void configure(ResourceServerSecurityConfigurer resources) { 
     // @formatter:off 
     resources 
       .resourceId(RESOURCE_ID).tokenStore(new JwtTokenStore(jwtAccessTokenConverter)); 
     // @formatter:on 
    } 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     // @formatter:off 
     http 
       .csrf().disable() 
       .authorizeRequests() 
       .antMatchers("/api/**").authenticated(); 
     // @formatter:on 
    } 
} 

@Configuration 
@EnableAuthorizationServer 
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { 
    @Autowired 
    private JwtAccessTokenConverter jwtAccessTokenConverter; 

    private TokenStore tokenStore = new JwtTokenStore(jwtAccessTokenConverter); 

    @Autowired 
    @Qualifier("authenticationManagerBean") 
    private AuthenticationManager authenticationManager; 

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
     // @formatter:off 
     endpoints 
       .tokenStore(tokenStore) 
       .authenticationManager(authenticationManager) 
       .accessTokenConverter(jwtAccessTokenConverter); 
     // @formatter:on 
    } 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     // @formatter:off 
     clients 
       .inMemory() 
       .withClient("12345") 
       .authorizedGrantTypes("password", "refresh_token") 
       .authorities("USER") 
       .scopes("read", "write") 
       .resourceIds(RESOURCE_ID) 
       .secret("54321") 
       .accessTokenValiditySeconds(2592000) // 30 days 
       .refreshTokenValiditySeconds(3888000); // 15 days more than access token 
     // @formatter:on 
    } 
} 

}

私はエラーが生成されている行にブレークポイントを配置した、とTokenEnhancerがヌルであるように、それは私には見えます、私はそれが問題を引き起こしていると思いますが、なぜそれがnullであるのか分かりません。ドキュメントを見ると、TokenEnhancerは単純にTokenConverterであり、私はこのクラスでBeanとして定義しています。

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private Environment env; 

    @Autowired 
    private CustomUserDetailsService userDetailsService; 

    @Autowired 
    private AccountAuthenticationProvider accountAuthenticationProvider; 

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

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

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

    @Bean 
    public JwtAccessTokenConverter jwtAccessTokenConverter() { 
     final JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); 
     jwtAccessTokenConverter.setSigningKey(env.getProperty("jwt.secret")); 
     return jwtAccessTokenConverter; 
    } 

} 

答えて

0

私はこれを理解することができました。私はJdbcTokenStore()にトークンストアをセットアップする必要があり、今は正常に動作します。以下は、私のデータベースでoauth側のために使用したデータベース構造です。

DROP TABLE IF EXISTS `oauth_access_token`; 
CREATE TABLE `oauth_access_token` (
    `token_id` varchar(255) DEFAULT NULL, 
    `token` mediumblob, 
    `authentication_id` varchar(255) NOT NULL, 
    `user_name` varchar(255) DEFAULT NULL, 
    `client_id` varchar(255) DEFAULT NULL, 
    `authentication` mediumblob, 
    `refresh_token` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`authentication_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

DROP TABLE IF EXISTS `oauth_approvals`; 
CREATE TABLE `oauth_approvals` (
    `userId` varchar(255) DEFAULT NULL, 
    `clientId` varchar(255) DEFAULT NULL, 
    `scope` varchar(255) DEFAULT NULL, 
    `status` varchar(10) DEFAULT NULL, 
    `expiresAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    `lastModifiedAt` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

DROP TABLE IF EXISTS `oauth_client_details`; 
CREATE TABLE `oauth_client_details` (
    `client_id` varchar(255) NOT NULL, 
    `resource_ids` varchar(255) DEFAULT NULL, 
    `client_secret` varchar(255) DEFAULT NULL, 
    `scope` varchar(255) DEFAULT NULL, 
    `authorized_grant_types` varchar(255) DEFAULT NULL, 
    `web_server_redirect_uri` varchar(255) DEFAULT NULL, 
    `authorities` varchar(255) DEFAULT NULL, 
    `access_token_validity` int(11) DEFAULT NULL, 
    `refresh_token_validity` int(11) DEFAULT NULL, 
    `additional_information` varchar(4096) DEFAULT NULL, 
    `autoapprove` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`client_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

DROP TABLE IF EXISTS `oauth_client_token`; 
CREATE TABLE `oauth_client_token` (
    `token_id` varchar(255) DEFAULT NULL, 
    `token` mediumblob, 
    `authentication_id` varchar(255) NOT NULL, 
    `user_name` varchar(255) DEFAULT NULL, 
    `client_id` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`authentication_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

DROP TABLE IF EXISTS `oauth_code`; 
CREATE TABLE `oauth_code` (
    `code` varchar(255) DEFAULT NULL, 
    `authentication` mediumblob 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

DROP TABLE IF EXISTS `oauth_refresh_token`; 
CREATE TABLE `oauth_refresh_token` (
    `token_id` varchar(255) DEFAULT NULL, 
    `token` mediumblob, 
    `authentication` mediumblob 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

私のコードでは、たとえばTokenStoreを参照していました。

private TokenStore tokenStore = new JwtTokenStore(jwtAccessTokenConverter); 

@Override 
     public void configure(ResourceServerSecurityConfigurer resources) { 
      resources.resourceId(RESOURCE_ID).tokenStore(new JwtTokenStore(jwtAccessTokenConverter)); 
     } 

私はTokenStore Beanを作成しました。

@Autowired 
    DataSource dataSource; 

    @Bean 
    public TokenStore tokenStore() { 
     return new JdbcTokenStore(dataSource); 
    } 

次にトークンストアとして使用してください。

@Autowired 
private TokenStore tokenStore; 

public void configure(ResourceServerSecurityConfigurer resources) { 
      resources.resourceId(RESOURCE_ID).tokenStore(tokenStore); 
     } 
関連する問題