当前位置: 首页 > 知识库问答 >
问题:

在Spring启动中使用Graqql进行身份验证

申屠俊发
2023-03-14

我正在使用GraphQL进行一个Spring启动项目。我使用的是Graphql-java工具和Graphql-sping-boot-starter。正如您在下面的java配置文件中看到的那样,我设法用Spring Security配置了安全性和会话管理。

现在“/graphql”路径是安全的(只能通过发送请求http头中的“基本http身份验证”或会话令牌(x-auth-token)来访问它)。在任何GraphQL操作上使用“基本http身份验证”进行身份验证将启动一个新会话,并在报头中发回新会话令牌,该令牌可进一步用于继续该会话。

如何让匿名用户访问一些GraphQL查询/变异,以保持上述行为?

如果我更改antMatchers(“/graphql”)。authenticated()到antMatchers(“/graphql”)。permitAll()为了允许匿名访问,即使我尝试使用“基本http身份验证”进行身份验证,也不再调用我的自定义身份验证提供程序

谢谢!

以下是我的配置:

@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();
    }

}

共有2个答案

龙兴贤
2023-03-14

我们使用了. antMatcher("/graql"). permitAll(),而不是. antMatcher("/graql"). permitAll(),然后我们删除了. http pBasic(),并删除了自定义的[code]验证提供程序。现在安全配置如下:

@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”的会话属性。这就是当您发出一个请求时,Spring需要能够自动恢复上下文的全部内容,该请求的头设置为“x-auth-Token”,该头设置为登录操作中获得的会话令牌的值。

由于,现在也允许匿名通话。蚂蚁匹配器(“/graphql”)。permitAll()在服务层,在公共方法上,我们可以使用如下注释:@Preauthorize(“isAnonymous()hasRole(“USER”)”)

郭辉
2023-03-14

即使需要使用permitAll(),您仍然可以使用AOP为解析器方法创建合理的默认值。

您可以创建默认需要身份验证的自定义安全方面。

例如,可以使用注释来标记不安全的方法。

详情见我的博文:https://michalgebauer.github.io/spring-graphql-security

 类似资料:
  • 实际上,我们正在开发一个应用程序,在Spring boot 1.5中,通过oauth2实现的Spring security完成身份验证和授权,现在我们有一个要求,在身份验证部分,拆分身份验证,并将身份验证部分转移到第三方,即SAML集成, 流程:登录- 如何在my spring security中仅使用userid授权用户,并生成自定义令牌(自定义任何spring security筛选器), 如何

  • 我正在尝试使与和一起工作。我试着按照spring-boot-sample-secure和spring-boot-sample-web-secure中的指南去做,但是我没有让它起作用。 我正在尝试构建一个没有任何ui交互的REST应用程序。因此,我发现这两个样品都不完全适合我的目的。目前我的解决方案是使用AOP。 解决方案对我有效。然而,我想知道这是否是一个好的解决方案。我很好奇是否有更好的解决办法

  • 问题内容: 在我的iOS应用程序中,我想使用WKWebView在应用程序中包装外部URL 。此URL需要基本身份验证(它需要用户和密码凭据,如以下屏幕截图所示)。 经过一番调查,我尝试使用 didReceiveAuthenticationChallengemethod来启用自动 登录,因此我不了解它的工作原理。 这是我的代码。 I’m facing with this exception: If

  • 我想为登录创建自定义endpoint。 当密码和用户名正确时,它可以正常工作,但对于不正确的数据返回200和登录表单而不是401。 public-class-SecurityConfiguration扩展了WebSecurityConfigurerAdapter{private-final-UserDetailsService-UserDetailsService; }

  • 下面是我得到的错误(堆栈跟踪中列出的最后几个原因) 它似乎不喜欢contextSource bean的constructor-arg中列出的URL,尽管我不确定原因。 另外,我怀疑这个配置的其他部分是不正确的。例如,我在ldap-server标记和contextSource bean中定义了ldap服务器URL。这似乎是不必要的重复,但在示例中是这样做的。有人能好好看看配置,以确保它是正常的吗?

  • 我正在尝试使用spring security 2.0.3进行LDAP身份验证 下面是我的配置 我应该在哪里提到域名?