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

Similar questions
K
KhanTengri2011-06-17 23:56:41
Get from a remote web page?</a> <a class="content__item-button" href="/q/get-title-from-a-remote-web-page"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" class=""> <path fill-rule="evenodd" d="M15 14a1.002 1.002 0 01-1.703.71h-.004l-.003-.01-1.704-1.7H3c-1.104 0-2-.9-2-2V3c0-1.1.896-2 2-2h10c1.104 0 2 .9 2 2v11zM5 6c.552 0 1 .45 1 1s-.448 1-1 1-1-.45-1-1 .448-1 1-1zm3 0c.552 0 1 .45 1 1s-.448 1-1 1-1-.45-1-1 .448-1 1-1zm3 0c.552 0 1 .45 1 1s-.448 1-1 1-1-.45-1-1 .448-1 1-1z"></path> </svg> <span class="dark">6</span><span class="dn">Reply</span> </a> </div> </div><div class="content__item"> <div class="content__item-img name-color-D"> <span>D</span></div> <div class="content__item-content"> <div class="content__item-row"> <a href="/q/how-to-connect-2-computers-on-different-networks-using-sockets">Daniel</a><span>2018-02-17 06:39:43</span></div> <a class="content__item-title similar" href="/q/how-to-connect-2-computers-on-different-networks-using-sockets">How to connect 2 computers on different networks using sockets.?</a> <a class="content__item-button" href="/q/how-to-connect-2-computers-on-different-networks-using-sockets"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" class=""> <path fill-rule="evenodd" d="M15 14a1.002 1.002 0 01-1.703.71h-.004l-.003-.01-1.704-1.7H3c-1.104 0-2-.9-2-2V3c0-1.1.896-2 2-2h10c1.104 0 2 .9 2 2v11zM5 6c.552 0 1 .45 1 1s-.448 1-1 1-1-.45-1-1 .448-1 1-1zm3 0c.552 0 1 .45 1 1s-.448 1-1 1-1-.45-1-1 .448-1 1-1zm3 0c.552 0 1 .45 1 1s-.448 1-1 1-1-.45-1-1 .448-1 1-1z"></path> </svg> <span class="dark">2</span><span class="dn">Reply</span> </a> </div> </div><div class="content__item"> <div class="content__item-img name-color-A"> <span>A</span></div> <div class="content__item-content"> <div class="content__item-row"> <a href="/q/how-does-a-double-for-loop-work">Andrey Kulagin</a><span>2020-04-24 20:59:10</span></div> <a class="content__item-title similar" href="/q/how-does-a-double-for-loop-work">How does a double for loop work?</a> <a class="content__item-button" href="/q/how-does-a-double-for-loop-work"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" class=""> <path fill-rule="evenodd" d="M15 14a1.002 1.002 0 01-1.703.71h-.004l-.003-.01-1.704-1.7H3c-1.104 0-2-.9-2-2V3c0-1.1.896-2 2-2h10c1.104 0 2 .9 2 2v11zM5 6c.552 0 1 .45 1 1s-.448 1-1 1-1-.45-1-1 .448-1 1-1zm3 0c.552 0 1 .45 1 1s-.448 1-1 1-1-.45-1-1 .448-1 1-1zm3 0c.552 0 1 .45 1 1s-.448 1-1 1-1-.45-1-1 .448-1 1-1z"></path> </svg> <span class="dark">1</span><span class="dn">Reply</span> </a> </div> </div> </div> </div> </div> <div class="content find"> <p class="find__p">Didn't find what you were looking for?</p><a class="find__btn" href="#!">Ask your question</a> </div> <div class="find sm"> <p class="find__title">Ask a Question </p> <form class="find__form" action="#!"> <input class="find__input" type="text" placeholder="Ask your question here"> <button class="find__btn" type="submit"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 16 16" class="nBqR1"><path fill-rule="evenodd" d="M12.696 7.256L9.657 4.217a1 1 0 00-1.415 1.414l1.344 1.344H3.949a1.001 1.001 0 000 2h5.637l-1.344 1.343a1.002 1.002 0 000 1.415c.391.39 1.024.39 1.415 0l3.039-3.04A.993.993 0 0013 7.975a.997.997 0 00-.293-.708l-.011-.011z"></path></svg></button> </form> <p class="find__span">731 491 924 answers to any question</p> </div> </div> <aside class="banners"> <p>banners </p> </aside> </div> </main> </div> <script src="/assets/theme/js/highlight/highlight.min.js"></script> <script src="/assets/theme/js/app.min.js?_v=20220404145216"> </script> <script>hljs.highlightAll();</script> </body> </html>