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然后它工作! –