zuul网关在jwt身份验证后未重定向到微服务url

时间:2019-12-10 09:16:33

标签: java spring-security jwt microservices netflix-zuul

我将Zuul用作api网关,以通过在标头中传递jwt令牌来认证用户详细信息, 以下是我在zuul api网关中的Web安全配置文件

@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityCongurer extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception{

         http
            .csrf().disable()
                // make sure we use stateless session; session won't be used to store user's state.
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)     
            .and()
                // handle an authorized attempts 
                .exceptionHandling().authenticationEntryPoint((req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED))  
            .and()
               // Add a filter to validate the tokens with every request
               .addFilterAfter(new JwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
            // authorization requests config
            .authorizeRequests()
               // allow all who are accessing "auth" service
               .antMatchers(HttpMethod.POST, "/authapi/auth").permitAll()  
               // must be an admin if trying to access admin area (authentication is also required here)
               .antMatchers("/authapi/user/**").hasRole("ADMIN")
               // Any other request must be authenticated
               .anyRequest().authenticated(); 
    }

}

下面是我的身份验证过滤器类

public class JwtAuthorizationFilter extends OncePerRequestFilter{
    @Autowired
    public JwtProperties jwtProperties;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
            // Read the Authorization header, where the JWT token should be
            String header = request.getHeader(JwtProperties.HEADER_STRING);

            // If header does not contain BEARER or is null delegate to Spring impl and exit
            if (header == null || !header.startsWith(JwtProperties.TOKEN_PREFIX)) {
                chain.doFilter(request, response);
                return;
            }

            String token = request.getHeader(JwtProperties.HEADER_STRING)
                    .replace(JwtProperties.TOKEN_PREFIX,"");


            try {   // exceptions might be thrown in creating the claims if for example the token is expired

                // 4. Validate the token
                Claims body = Jwts.parser()
                        .setSigningKey(JwtProperties.SECRET.getBytes())
                        .parseClaimsJws(token)
                        .getBody();

                String value  = String.valueOf(body.get("role"));
                String valuerole = value.substring(12,22);
                 GrantedAuthority authorityyy = new SimpleGrantedAuthority(valuerole);

                String username = body.getSubject();
                if(username != null) {
                    List<GrantedAuthority> authorities = new ArrayList<>();
                    authorities.add(authorityyy);
                    // 5. Create auth object
                    // UsernamePasswordAuthenticationToken: A built-in object, used by spring to represent the current authenticated / being authenticated user.
                    // It needs a list of authorities, which has type of GrantedAuthority interface, where SimpleGrantedAuthority is an implementation of that interface
                     UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                             username, body.get("password"),authorities);

                     // 6. Authenticate the user
                     // Now, user is authenticated
                     SecurityContextHolder.getContext().setAuthentication(auth);
                }

            } catch (Exception e) {
                // In case of failure. Make sure it's clear; so guarantee user won't be authenticated
                SecurityContextHolder.clearContext();
            }

            // Continue filter execution
            chain.doFilter(request, response); // last pointer
    }
}

当指针指向chain.doFilter(request,response);时,我一直停留在这里。行,它会显示未经授权的401错误。

这是我的application.properties,

server.port=8762
spring.application.name=zuul-server
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
zuul.ignored-services=*

eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=true
zuul.routes.auth-service.service-id=AUTH-SERVICE
zuul.routes.auth-service.path=/authapi/**



zuul.routes.auth-service.sensitive-headers=Cookie,Set-Cookie 
ribbon.ReadTimeout=60000

上面是我的zuul api网关文件。

现在添加用于生成令牌的用户身份验证服务文件。

下面是用于用户身份验证的Web安全配置文件,

@Configuration
@EnableWebSecurity
@ComponentScan("com.userManagementService.ServiceUserCredentials.*")
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfigurer extends WebSecurityConfigurerAdapter{
    @Autowired
    public UserOperationService userOperationService;
    @Autowired
    public MyUserDetailsService myUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception{

        http
        .csrf().disable()
         // make sure we use stateless session; session won't be used to store user's state.
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
            // handle an authorized attempts 
            .exceptionHandling().authenticationEntryPoint((req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED))
        .and()
        // Add a filter to validate user credentials and add token in the response header

        // What's the authenticationManager()? 
        // An object provided by WebSecurityConfigurerAdapter, used to authenticate the user passing user's credentials
        // The filter needs this auth manager to authenticate the user.
        .addFilter(new JwtAuthenticationFilter(authenticationManager()))
        .authorizeRequests()
        // allow all POST requests 
        .antMatchers(HttpMethod.POST, "/auth").permitAll()
        // any other requests must be authenticated
        .anyRequest().authenticated();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();

    }

    @Bean
    DaoAuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setUserDetailsService(myUserDetailsService);
        return daoAuthenticationProvider;
    }
}

0 个答案:

没有答案