3

我嘗試創建spring rest服務,whis由我自己的oauth2資源服務器進行驗證。我創建資源服務器:oauth2的其他服務:無法找到令牌的訪問令牌

@Configuration 
@EnableResourceServer 
protected static class ResourceServer extends ResourceServerConfigurerAdapter { 

    @Autowired 
    private TokenStore tokenStore; 

    @Override 
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception { 
     resources.tokenStore(tokenStore).resourceId("mobileapp"); 
    } 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests().antMatchers("/api/shop /**").authenticated().and() 
       .authorizeRequests().antMatchers("/auth/**").anonymous(); 
    } 

} 

授權服務器:

@Configuration 
@EnableAuthorizationServer 
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { 

    @Autowired 
    private AuthenticationManager auth; 

    @Autowired 
    private DataSource dataSource; 

    @Autowired 
    private BCryptPasswordEncoder passwordEncoder; 

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

    @Bean 
    protected AuthorizationCodeServices authorizationCodeServices() { 
     return new JdbcAuthorizationCodeServices(dataSource); 
    } 

    @Override 
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { 
     security.passwordEncoder(passwordEncoder); 
    } 

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
     endpoints 
       .authorizationCodeServices(authorizationCodeServices()) 
       .authenticationManager(auth) 
       .tokenStore(tokenStore()) 
       .approvalStoreDisabled(); 
    } 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.jdbc(dataSource) 
       .passwordEncoder(passwordEncoder); 
       .withClient("mobile") 
       .authorizedGrantTypes("password", "refresh_token") 
       .authorities("ROLE_CLIENT") 
       .scopes("read", "write", "trust") 
       .autoApprove(true) 
       .resourceIds("mobileapp") 
       .secret("123456"); 
    } 

當我嘗試接收來自服務器的訪問令牌,使用curl:

捲曲-X POST -vu移動:123456 http://localhost:8080/oauth/token -H 「Accept:application/json」-d 「password = test123 & username = [email protected] & grant_type =密碼&範圍=讀& client_secret = 123456 & CLIENT_ID =移動 「

我得到這個錯誤作爲響應消息:

{ 」錯誤「: 」SERVER_ERROR「, 」ERROR_DESCRIPTION「:」 的java .io.NotSerializableException: org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder「}

在Tomcat的日誌,還有

ossoptoken.store.JdbcTokenStore - 無法找到訪問令牌 令牌

編輯:密碼編碼器的 bean定義:

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

這個bean是在類中創建,在其中聲明瞭OAuth2Config和ResourceServer。

我檢查了代碼,發現哪個表彈簧使用和表是空的。我的問題是:它應該是自動生成還是我的代碼有問題?

在此先感謝您的幫助。

+0

你可以使用'BCryptPasswordEncoder' bean的'@ Bean'定義更新問題嗎? – sthzg

+0

我添加了BCryptPasswordEncoder bean定義。 – Marcin

+0

謝謝,'@ Bean'看起來很好,在我看來(儘管你可以使用它的類型的PasswordEncoder接口)。當我在本地測試時,我必須使用加密的PW(如withClient(...)。secret(passwordEncoder.encode(「123456」))''設置'withClient(..)。secret(...)',但這並不能解釋序列化錯誤(它不會解釋一個'BadCredentials'響應,當我不對它進行編碼時,我會得到這個響應。當你沒有設置'security.passwordEncoder(...)'時,你是否檢查了一切正常? – sthzg

回答

4

重寫JdbcTokenStore類並將其替換爲此函數。

public OAuth2AccessToken readAccessToken(String tokenValue) { 
    OAuth2AccessToken accessToken = null; 

    try { 
     accessToken = new DefaultOAuth2AccessToken(tokenValue); 
    } 
    catch (EmptyResultDataAccessException e) { 
     if (LOG.isInfoEnabled()) { 
      LOG.info("Failed to find access token for token "+tokenValue); 
     } 
    } 
    catch (IllegalArgumentException e) { 
     LOG.warn("Failed to deserialize access token for " +tokenValue,e); 
     removeAccessToken(tokenValue); 
    } 

    return accessToken; 
} 

解決了您找不到訪問令牌的問題。請在OAuth2Config中使用此類。

0

您的模型必須具有未序列化的BCryptPasswordEncoder。在你的用戶bmodel中使其瞬變。

private transient BCryptPasswordEncoder passwordEncoder; 
相關問題