authentication in spring boot using graphql

后端 未结 2 1957

I’m working on a spring boot project with GraphQL. I\'m using graphql-java-tools and graphql-spring-boot-starter. I managed to configure security and session management with spr

2条回答
  •  时光说笑
    2021-02-02 18:09

    Instead of .antMatchers("/graphql").authenticated() we used .antMatchers("/graphql").permitAll(), then we removed .httpBasic() and also removed the custom AuthenticationProvider. Now the security configs look like this:

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

    Then we created a mutation for login that accepts the user's credentials and returns the session token. Here is the graphql schema:

    login(credentials: CredentialsInputDto!): String
    
    input CredentialsInputDto {
        username: String!
        password: String!
    }
    

    Basically the code we had in our custom AuthenticationProvider went into the service that is called by the login operation:

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

    The key is that we prepared the session context with the authenticated user's authentication and then we save it (in redis) as a session attribute called "SPRING_SECURITY_CONTEXT". This is all what spring needs to be able to automatically restore the context when you make a request having the "x-auth-token" header set with the value of the session token obtained from the login operation.

    Now also anonymous calls are allowed because of .antMatchers("/graphql").permitAll() and in the service layer, on public methods we can use annotations like this: @Preauthorize("isAnonymous() OR hasRole("USER")").

提交回复
热议问题