authentication in spring boot using graphql

后端 未结 2 1951

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")").

    0 讨论(0)
  • 2021-02-02 18:22

    Even though you need to use permitAll() you can still create reasonable default for your resolver methods using AOP.

    You can create your custom security aspect that will require authentication by default.

    Unsecured methods may be marked for example using annotation.

    See my blog post for details: https://michalgebauer.github.io/spring-graphql-security

    0 讨论(0)
提交回复
热议问题