source

graphql을 사용하여 스프링 부트에서 인증

factcode 2023. 10. 16. 22:06
반응형

graphql을 사용하여 스프링 부트에서 인증

저는 GraphQL과 봄맞이 부츠 프로젝트를 진행하고 있습니다.graphql-java-tools 및 graphql-spring-boot-starter를 사용하고 있습니다.아래 java config 파일에서 볼 수 있듯이 spring security로 security 및 session management를 구성할 수 있었습니다.

이제 "/graphql" 경로가 보호됩니다("기본 http 인증" 또는 세션 토큰을 전송하는 경우에만 액세스할 수 있습니다).x-auth-token요청의 http 헤더에 ).GraphQL 작업에서 "기본 http 인증"을 사용하여 인증하면 새 세션이 시작되고 헤더에 새 세션 토큰이 반환되며, 해당 토큰은 해당 세션을 계속하는 데 추가로 사용될 수 있습니다.

위 동작을 유지하는 일부 GraphQL 쿼리/순열에 익명 사용자에게 액세스를 제공하는 방법은 무엇입니까?

내가 변하면antMatchers("/graphql").authenticated()로.antMatchers("/graphql").permitAll()익명 접근을 허용하기 위해, 내 관습은AuthenticationProvider"기본 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();
    }

}

대신에.antMatchers("/graphql").authenticated()우리가 쓰던.antMatchers("/graphql").permitAll(), 그 다음에 제거했습니다..httpBasic()그리고 관습도 없앴습니다.AuthenticationProvider. 보안 구성은 다음과 같습니다.

@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!
}

기본적으로 사용자 지정 Authentication Provider에 있는 코드는 로그인 작업에 의해 호출되는 서비스에 들어갔습니다.

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_CONTECT"라는 세션 속성으로 저장한다는 것입니다.로그인 작업에서 얻은 세션 토큰 값으로 "x-auth-token" 헤더가 설정된 요청을 할 때 자동으로 컨텍스트를 복원하기 위해 스프링이 필요한 모든 것입니다.

이제 익명의 전화도 가능합니다..antMatchers("/graphql").permitAll()서비스 계층에서는 다음과 같은 주석을 공용 방법에서 사용할 수 있습니다.@Preauthorize("isAnonymous()오어hasRole("USER")").

당신이 사용할 필요가 있음에도.permitAll()AOP를 사용하여 레졸버 메서드에 대한 적절한 기본값을 만들 수 있습니다.

기본적으로 인증이 필요한 사용자 지정 보안 측면을 만들 수 있습니다.

예를 들어 주석을 사용하여 보안되지 않은 방법을 표시할 수 있습니다.

자세한 내용은 내 블로그 게시물 보기: https://michalgebauer.github.io/spring-graphql-security

언급URL : https://stackoverflow.com/questions/45959234/authentication-in-spring-boot-using-graphql

반응형