M
M
mitaichik2017-07-18 18:29:27
Java
mitaichik, 2017-07-18 18:29:27

Spring: How to make authentication based on bearer token?

Good afternoon! I have a Spring MVC application. It receives requests with the header Authorization : Bearer ... Authorization, issuance of tokens goes outside of this application.
What I need: I need to get the user data for this token (the token and data are stored in the database) and inject the user object into the controller.
What tools out of the box are usually used for this? I understand that spring security, but I didn’t quite understand how to do this ...

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexander Kosarev, 2017-07-19
@mitaichik

  1. A class that implements Authentication .
    TokenAuthentication.java
    public class TokenAuthentication extends AbstractAuthenticationToken {
        private final Object principal;
        private final Object credentials;
        public TokenAuthentication(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
            super(authorities);
            this.principal = principal;
            this.credentials = credentials;
            this.setAuthenticated(true);
        }
        public TokenAuthentication(Object principal, Object credentials) {
            this(principal, credentials, null);
        }
        @Override
        public Object getPrincipal() {
            return principal;
        }
        @Override
        public Object getCredentials() {
            return credentials;
        }
    }

  2. The filter that will start the user authentication process. The filter should create an object of type Authentication and try to authenticate it using the AuthenticationManager .
    TokenHeaderAuthenticationFilter.java
    public class TokenHeaderAuthenticationFilter extends OncePerRequestFilter {
    
        private final AuthenticationManager authenticationManager;
    
        public TokenHeaderAuthenticationFilter(AuthenticationManager authenticationManager) {
            this.authenticationManager = authenticationManager;
        }
    
        @Override
        protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
            if (SecurityContextHolder.getContext().getAuthentication() != null && SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
            String headerValue = servletRequest.getHeader("X-Authorization");
            if (StringUtils.isEmpty(headerValue)) {
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
            String token = headerValue.split("\\s")[1];// ну или headerValue.replace("Bearer ")
            TokenAuthentication authenticationToken = new TokenAuthentication(null, token);
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(servletRequest));
    
            Authentication authenticationResult = authenticationManager.authenticate(authenticationToken);
            SecurityContextHolder.getContext().setAuthentication(authenticationResult);
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

  3. A class that implements the AuthenticationProvider . This class will authenticate the received data.
    TokenAuthenticationProvider.java
    public class TokenAuthenticationProvider implements AuthenticationProvider {
        @Override
        public boolean supports(Class<?> authentication) {
            return TokenAuthentication.class.isAssignableFrom(authentication);
        }
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            // здесь должна быть реализована логика аутентификации полученных данных
        }
    }

  4. The final touch is the configuration.
    SecurityConfig.java
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Bean
        public AuthenticationProvider tokenAuthenticationProvider() {
            return new TokenAuthenticationProvider();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.addFilterAfter(new TokenHeaderAuthenticationFilter(authenticationManagerBean()), BasicAuthenticationFilter.class)
                    .authenticationProvider(tokenAuthenticationProvider())
                    .authorizeRequests()
                    .anyRequest().authenticated();
        }
    }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question