1

我正在使用REST API,它在本地主機上偵聽,並且我想包含Spring Security。密碼授予和客戶端憑據授權完美地工作,我可以去檢查/ smarthouse和/ smarthouse2的安全數據。授權代碼授權

雖然,當我嘗試通過郵遞員使用授權代碼授予時,它給了我同樣的錯誤,並且我已到處檢查。我的項目在這裏:https://github.com/sharjak/Smarthouse。該操作全部發生在demoapplication文件夾中。

Authorization code in Postman

我的授權和資源服務器代碼:

@Configuration 
public class OAuth2ServerConfig { 

    @Configuration 
    @EnableResourceServer 
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 

     @Override 
     public void configure(HttpSecurity http) throws Exception { 
      http 
        .anonymous().disable() 
        .csrf().disable() 
        .authorizeRequests() 
        .anyRequest() 
        .authenticated().and() 
        .formLogin(); 
      } 
     } 

    @Configuration 
    @EnableAuthorizationServer 
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { 

     @Autowired 
     private TokenStore tokenStore; 

     @Autowired 
     private AuthenticationManager authenticationManager; 

     @Override 
     public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 

      clients.inMemory().withClient("my-trusted-client") 
        .authorizedGrantTypes("password","authorization_code","refresh_token", "implicit") 
        .authorities("ROLE_CLIENT","ROLE_TRUSTED_CLIENT","ROLE_USER") 
        .scopes("read", "write", "trust") 
        .resourceIds("oauth2-resource") 
        .secret("secret") 
        .accessTokenValiditySeconds(6000) 
        .and() 

        .withClient("my-client") 
        .authorizedGrantTypes("authorization_code", "implicit") 
        .authorities("ROLE_CLIENT", "ROLE_USER") 
        .scopes("read","trust", "write") 
        .resourceIds("oauth2-resource") 
        .accessTokenValiditySeconds(6000) 
        .and() 

        .withClient("my-client-with-secret") 
        .authorizedGrantTypes("client_credentials","password") 
        .authorities("ROLE_CLIENT", "ROLE_USER") 
        .scopes("read", "trust", "write") 
        .resourceIds("oauth2-resource") 
        .secret("secret") 
        .accessTokenValiditySeconds(6000); 
     } 

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

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

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

代碼Websecurity服務器:

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private ClientDetailsService clientDetailsService; 

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

     http 
       .anonymous().disable() 
       .csrf().disable() 
       .authorizeRequests() 
       .antMatchers("/smarthouse", "smarthouse2", "/user").permitAll() 
       .and() 
       .formLogin(); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.inMemoryAuthentication() 
       .withUser("admin").password("password").roles("ADMIN") 
       .and() 
       .withUser("sander").password("Sander123").roles("USER"); 
    } 

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

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

    @Bean 
    @Autowired 
    public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){ 
     TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler(); 
     handler.setTokenStore(tokenStore); 
     handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService)); 
     handler.setClientDetailsService(clientDetailsService); 
     return handler; 
    } 

    @Bean 
    @Autowired 
    public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception { 
     TokenApprovalStore store = new TokenApprovalStore(); 
     store.setTokenStore(tokenStore); 
     return store; 
    } 
} 

堆棧跟蹤,當我嘗試與用戶登錄:

org.springframework.security.authentication.InsufficientAuthenticationException: User must be authenticated with Spring Security before authorization can be completed. 
     at org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(AuthorizationEndpoint.java:138) 

我是一個初學者,但它似乎是一個小問題來解決。誰能幫我?

+0

所以你想要的是使用郵差獲取訪問令牌? –

+0

是的,問題是,當我與用戶一起登錄時,它沒有給我授權碼,但告訴我用戶必須通過驗證。如果我嘗試從瀏覽器登錄,它會給我一個錯誤在安全上下文中找不到認證對象。 –

回答

0

你只需要改變你從WebSecurityConfigconfigure方法是什麼如下:

http 
    .authorizeRequests() 
     .antMatchers("/login", "/favicon.ico", 
      "/oauth/confirm_access", "/oauth/token", "/smarthouse", 
      "smarthouse2", "/user").permitAll() 
     .anyRequest().authenticated().and() 
    .csrf().disable(); 

爲什麼你需要禁用匿名訪問? 另一點是,匹配者的訂單被宣佈爲重要事項。

我已經克隆你的回購,併爲我工作。

+0

當我不禁用匿名時,它給了我一個錯誤訪問被拒絕,用戶是匿名的。我試過了,但它仍然給我帶來了同樣的錯誤:在SecurityContext中找不到認證對象。它看起來像一個無限循環,在那裏用戶得到認證,然後重定向到授權頁面,但無法檢索用戶名和密碼,然後重定向回登錄頁面。 –

+0

剛剛找到了解決方案,我在application.yml中配置了錯誤。必須擦除security.oauth2.resource.filer-order:3然後它工作! –