代码之家  ›  专栏  ›  技术社区  ›  Dorinel Panaite

未调用Spring筛选器

  •  1
  • Dorinel Panaite  · 技术社区  · 8 年前

    我一直在跟踪 this 在Spring中获得JWT身份验证的教程,但是由于某些原因,过滤器不适合我。我已经从Github下载了这个教程项目,而且它是有效的,但是我的没有,我也不明白为什么。。。

    我将在下面发布一些代码(不要介意Kotlin+Java的混合,我试着用Java实现安全配置,认为这可能是个问题)

    Initializer.kt
    
    class Initializer : WebApplicationInitializer {
    @Throws(ServletException::class)
    override fun onStartup(container: ServletContext) {
        val context = AnnotationConfigWebApplicationContext()
        context.scan("com.newyorkcrew.server.config")
        context.scan("com.newyorkcrew.server.domain")
    
        val dispatcher = container.addServlet("dispatcher", DispatcherServlet(context))
        dispatcher.setLoadOnStartup(1)
        dispatcher.addMapping("/api/*")
    }
    }
    

    WebConfig.kt
    
    @Bean
    fun propertySourcesPlaceholderConfigurer(): PropertySourcesPlaceholderConfigurer {
    return PropertySourcesPlaceholderConfigurer()
     }
    
    @Configuration
    @Import(JPAConfig::class)
    @EnableWebMvc
    @ComponentScan("com.newyorkcrew.server")
    @PropertySources(PropertySource(value = ["classpath:local/db.properties",     "classpath:local/security.properties"]))
    open class WebConfig {
    
    @Bean
    open fun corsConfigurer(): WebMvcConfigurer {
        return object : WebMvcConfigurer {
            override fun addCorsMappings(registry: CorsRegistry?) {
                registry!!.addMapping("/**")
                        .allowedOrigins("http://localhost:4200", "http://localhost:8080", "http://localhost:8081")
                        .allowedMethods("GET", "PUT", "POST", "DELETE")
            }
        }
    }
    }
    

    WebSecurity.java
    
        @Configuration
    @EnableWebSecurity
    @ComponentScan("com.newyorkcrew.server.config")
    public class WebSecurity extends WebSecurityConfigurerAdapter {
        public static String SECRET;
    
        @Value("{security.secret}")
        private void setSECRET(String value) {
            SECRET = value;
        }
    
        @Value("{security.expiration}")
        public static long EXPIRATION_TIME;
    
        @Value("{security.header}")
        public static String HEADER;
    
        @Value("{security.prefix}")
        public static String PREFIX;
    
        public static String SIGN_UP_URL;
    
        @Value("${security.signupurl}")
        private void setSignUpUrl(String value) {
            SIGN_UP_URL = value;
        }
    
        @Autowired
        private UserDetailsService userDetailsService;
    
        public WebSecurity(UserDetailsService userDetailsService) {
            this.userDetailsService = userDetailsService;
        }
    
        @Bean
        public BCryptPasswordEncoder bCryptPasswordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.cors().and().csrf().disable().authorizeRequests()
                    .antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .addFilter(new JWTAuthenticationFilter(authenticationManager()))
                    .addFilter(new JWTAuthorizationFilter(authenticationManager()));
        }
    
        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
        }
    
        @Bean
        CorsConfigurationSource corsConfigurationSource() {
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/api/**", new CorsConfiguration().applyPermitDefaultValues());
            return source;
        }
    

    }

    我还实现了UserDetailService、JWTAuthenticationFilter和JWTAuthorizationFilter,但是只要它们没有被命中,我认为它们并不重要。

    我使用configs已经有一段时间了,它们也工作了,但是当SecurityConfig被添加时,它被初始化了,但是过滤器由于某种原因不工作。

    如果需要更多的代码,我会发布。

    编辑:根据请求,实现JWTAuthenticationFilter。

    open class JWTAuthenticationFilter(private val authManager: AuthenticationManager) : UsernamePasswordAuthenticationFilter() {
        override fun attemptAuthentication(request: HttpServletRequest?, response: HttpServletResponse?): Authentication {
            try {
                // Build the user DTO from the request
                val userDTO = Gson().fromJson(convertInputStreamToString(request?.inputStream), UserDTO::class.java)
    
                // Build the user from the DTO
                val user = UserConverter().convertDtoToModel(userDTO)
    
                // Try to authenticate
                return authManager.authenticate(UsernamePasswordAuthenticationToken(user.email, user.password, ArrayList()))
            } catch (e: Exception) {
                throw RuntimeException(e)
            }
        }
    
        override fun successfulAuthentication(request: HttpServletRequest?, response: HttpServletResponse?,
                                              chain: FilterChain?, authResult: Authentication?) {
            val token = Jwts.builder()
                    .setSubject(authResult?.principal.toString())
                    .setExpiration(Date(System.currentTimeMillis() + EXPIRATION_TIME))
                    .signWith(SignatureAlgorithm.HS512, SECRET.toByteArray())
                    .compact()
            response?.addHeader(HEADER, "$PREFIX $token")
        }
    }
    

    如有任何帮助,我们将不胜感激。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Dorinel Panaite    8 年前

    我的解决办法是放弃科特林。用相同的配置启动了一个新的Spring项目,它很简单。我很难过,因为我想在Kt做这个项目,但也许我做错了。。