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“ )“)。