0

我正在使用graphql進行spring引導項目。我正在使用graphql-java-tools和graphql-spring-boot-starter。我設法用spring安全性來配置安全性和會話管理,就像你在下面的java配置文件中看到的一樣。在使用graphql的spring引導中進行身份驗證

現在「/ graphql」路徑是安全的(它只能在請求的http頭中發送「基本http認證」或會話令牌(x-auth-token))。在任何graphql操作上使用「基本http認證」進行認證將開始一個新的會話,並將新的會話令牌發送回頭,並且該令牌可用於繼續該會話。

如何讓匿名用戶訪問一些graphql查詢/突變保持上述行爲?如果我將antMatchers(「/ graphql」)。authenticated()更改爲antMatchers(「/ graphql」)。permitAll()以允許匿名訪問,那麼我的自定義AuthenticationProvider不會再被調用,即使當我嘗試使用「基本http認證」進行認證。

謝謝!

這裏是我的CONFIGS:

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

@Autowired 
private AuthenticationProvider authenticationProvider; 

@Override 
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) { 
    authenticationManagerBuilder.authenticationProvider(authenticationProvider); 
} 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
      .csrf().disable() 
      .authorizeRequests() 
      .antMatchers("/graphql").authenticated() 
      .and() 
      .requestCache() 
      .requestCache(new NullRequestCache()) 
      .and() 
      .httpBasic() 
      .and() 
      .headers() 
      .frameOptions().sameOrigin() // needed for H2 web console 
      .and() 
      .sessionManagement() 
      .maximumSessions(1) 
      .maxSessionsPreventsLogin(true) 
      .sessionRegistry(sessionRegistry()); 
} 

@Bean 
public SessionRegistry sessionRegistry() { 
    return new SessionRegistryImpl(); 
} 

@Bean 
public HttpSessionEventPublisher httpSessionEventPublisher() { 
    return new HttpSessionEventPublisher(); 
} 
} 

@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 180) 
public class HttpSessionConfig { 

@Bean 
public HttpSessionStrategy httpSessionStrategy() { 
    return new HeaderHttpSessionStrategy(); 
} 

} 

回答

0

相反.antMatchers的( 「/ graphql」)認證(),我們使用.antMatchers( 「/ graphql」)permitAll()。 ,然後我們刪除了.httpBasic(),並刪除了自定義的AuthenticationProvider。現在,安全CONFIGS這個樣子:

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
      .csrf().disable() 
      .authorizeRequests() 
      .antMatchers("/graphql").permitAll() 
      .and() 
      .requestCache() 
      .requestCache(new NullRequestCache()) 
      .and() 
      .headers() 
      .frameOptions().sameOrigin() // needed for H2 web console 
      .and() 
      .sessionManagement() 
      .maximumSessions(1) 
      .maxSessionsPreventsLogin(true) 
      .sessionRegistry(sessionRegistry()); 
} 

@Bean 
public SessionRegistry sessionRegistry() { 
    return new SessionRegistryImpl(); 
} 

@Bean 
public HttpSessionEventPublisher httpSessionEventPublisher() { 
    return new HttpSessionEventPublisher(); 
} 

}

然後,我們創建了登錄,它接受用戶的憑據,並返回會話令牌的突變。這裏是graphql模式:

login(credentials: CredentialsInputDto!): String 

input CredentialsInputDto { 
    username: String! 
    password: String! 
} 

基本上,我們在我們的自定義有代碼的AuthenticationProvider走進由登錄操作調用的服務:

public String login(CredentialsInputDto credentials) { 
    String username = credentials.getUsername(); 
    String password = credentials.getPassword(); 

    UserDetails userDetails = userDetailsService.loadUserByUsername(username); 

    ... credential checks and third party authentication ... 

    Authentication authentication = new UsernamePasswordAuthenticationToken(username, password, userDetails.getAuthorities()); 
    SecurityContextHolder.getContext().setAuthentication(authentication); 
    httpSession.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext()); 
    return httpSession.getId(); 
} 

的關鍵是,我們準備了會議背景與經過身份驗證的用戶身份驗證一起使用,然後我們將其保存爲(在redis中)作爲名爲「SPRING_SECURITY_CONTEXT」的會話屬性。這就是當您使用從登錄操作獲得的會話令牌的值設置「x-auth-token」頭部的請求時,spring需要能夠自動恢復上下文。 因爲.antMatchers(「/ graphql」)。permitAll(),並且在服務層中,在公共方法中,我們可以使用如下注釋:@Preauthorize(「isAnonymous()or hasRole(」USER「 )「)。