2017-01-05 142 views
0

私はSpring Bootアプリケーションを持っていますが、アプリケーションの前で春のセキュリティを実装するまでは問題ありません。これは、トークンベースの認証を持つRESTful APIです。間欠的に、アプリケーションを再起動すると、認証されていない場合は401/403などの正しい応答が返され、ユーザーにアクセスが許可されている場合は他のコードが返されます。これはWebLogicにデプロイされています。URIでHTTPリクエストのマッピングが見つかりません

2017-01-05 14:12:51.164 WARN 11252 --- [ (self-tuning)'] o.s.web.servlet.PageNotFound    : No mapping found for HTTP request with URI [/user] in DispatcherServlet with name 'dispatcherServlet' 

WebApplication.java

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class }) 
public class WebApplication extends SpringBootServletInitializer implements WebApplicationInitializer { 

    public static void main(String[] args) { 
     Object[] sources = new Object[2]; 
     sources[0] = WebConfiguration.class; 
     sources[1] = WebSecurityConfiguration.class; 
     SpringApplication.run(sources, args); 
    } 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { 
     return builder.sources(WebApplication.class); 
    } 

} 

WebConfiguration.java

@Configuration 
@ComponentScan(basePackages = { "com.controller", "com.service", "com.dao"}) 
@EnableAutoConfiguration(exclude = { 
     DataSourceAutoConfiguration.class }) 
public class WebConfiguration extends WebMvcConfigurerAdapter { 

private static final Logger logger = LoggerFactory.getLogger(WebConfiguration.class); 

/** 
* Setup a simple strategy: use all the defaults and return XML by default 
* when not sure. 
*/ 
@Override 
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { 
    configurer.defaultContentType(MediaType.APPLICATION_JSON).mediaType("json", MediaType.APPLICATION_JSON) 
      .mediaType("xml", MediaType.APPLICATION_XML); 
} 

@Bean(name = "entityManagerFactory") 
public EntityManagerFactory getQmsEntityManagerFactory() { 
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); 
    em.setPersistenceUnitName(Config.PERSISTENCE_UNIT_NAME); 
    em.setPersistenceXmlLocation("META-INF/persistence.xml"); 
    em.setDataSource(getDataSource()); 
    em.setJpaVendorAdapter(getJpaHibernateVendorAdapter()); 
    em.afterPropertiesSet(); 
    return em.getObject(); 
} 

@Bean 
public HibernateJpaVendorAdapter getJpaHibernateVendorAdapter() { 
    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); 
    adapter.setShowSql(true); 
    // adapter.setDatabase("ORACLE"); 
    adapter.setDatabasePlatform("org.hibernate.dialect.Oracle10gDialect"); 
    return adapter; 
} 

@Bean(name="dataSource", destroyMethod = "") 
//http://stackoverflow.com/questions/19158837/weblogic-datasource-disappears-from-jndi-tree 
@Qualifier("dataSource") 
@Profile("weblogic") 
public DataSource dataSource() { 
    DataSource dataSource = null; 
    JndiTemplate jndi = new JndiTemplate(); 
    try { 
     dataSource = (DataSource) jndi.lookup("jdbc/datasource"); 
    } catch (NamingException e) { 
     logger.error("NamingException for jdbc/datasource", e); 
    } 
    return dataSource; 
} 

@Bean 
public WebMvcConfigurer corsConfigurer() { 
    return new WebMvcConfigurerAdapter() { 
     @Override 
     public void addCorsMappings(CorsRegistry registry) { 
      registry.addMapping("/**").allowedOrigins("*").allowedMethods("*"); 
     } 
    }; 
} 

}

WebSecurityConfiguration.java

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
@ComponentScan({ 
    "com.subject", 
    "com.custom" 
    }) 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 

@Autowired 
private StatelessAuthenticationFilter statelessAuthenticationFilter; 

@Autowired 
private RestAuthenticationEntryPoint unauthorizedHandler; 

@Autowired 
private CusAuthenticationProvider cusAuthenticationProvider; 


@Override 
protected void configure(AuthenticationManagerBuilder auth) { 
    auth.authenticationProvider(cusAuthenticationProvider); 
} 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .csrf().disable() 
     .securityContext() 
    .and() 
     .sessionManagement() 
     .sessionCreationPolicy(SessionCreationPolicy.STATELESS)    
    .and() 
     .authorizeRequests().anyRequest().authenticated() 
    .and() 
     .addFilterBefore(statelessAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) 
    .exceptionHandling().authenticationEntryPoint(unauthorizedHandler);  
} 

}

StatelessAuthenticationFilter.java

@Component 
public class StatelessAuthenticationFilter extends OncePerRequestFilter { 



@Inject 
private SubjectLookupService subjectLookupService; 

@Override 
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 
     throws IOException, ServletException { 

    SecurityContextHolder.getContext().setAuthentication(authenticateUser(request)); 

    filterChain.doFilter(request, response); 
} 

private Authentication authenticateUser(HttpServletRequest request) { 
    try { 
     String application = StringUtils.defaultString(request.getParameter("application")); 

     UserInfo me = subjectLookupService.getUserInfo(); 

     List<GrantedAuthority> roles = me.getRoles().stream()     
       .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName())).collect(Collectors.toList()); 

     UserDetails user = new User(me.getUsername(), "", roles); 

     Authentication authentication = new UserAuthentication(user); 

     return authentication; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

} 

それが動作するときController.java

@RestController 
public class Controller { 

@Autowired 
private QService qService; 

@PreAuthorize("hasAnyRole('view', 'admin')") 
@RequestMapping(value = "https://stackoverflow.com/q/{year}", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) 
public ResponseEntity<?> listQuotas(@PathVariable Integer year) { 

    return new ResponseEntity<>(qService.listQs(year), HttpStatus.OK); 
} 

@RequestMapping(value = "/user", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) 
public ResponseEntity<?> user(HttpServletRequest request) { 
    Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 
    return new ResponseEntity<>(auth.getPrincipal(), HttpStatus.OK); 
} 

@PreAuthorize("hasRole('shouldntauthorize')") 
@RequestMapping(value = "/unauthorized/{year}", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET) 
public ResponseEntity<?> unauthorized(@PathVariable Integer year) { 

    return new ResponseEntity<>(qService.listQs(year), HttpStatus.OK); 
} 

} 

は - 私はHTTPを使用して上記の方法のいずれかをヒットすることができるよ取得し、私は正しい応答を取得しています。それは働いていないとき、私は常に取得しています:

2017-01-05 14:18:47.506 WARN 11252 --- [ (self-tuning)'] o.s.web.servlet.PageNotFound    : No mapping found for HTTP request with URI [/user] in DispatcherServlet with name 'dispatcherServlet' 

私は春ブーツがアプリケーションを初期化するときもある正しいマッピングのURLを設定することをログで確認できます。

何が問題なのですか?

答えて

0

「断続的に」と言えば、私はこの問題がSpringのスタートアップコンフィギュレーションであると思う傾向があります。

だから、@ComponentScanが2回あり、パッケージが違うことに疲れています。

あなたはクラスWebSecurityConfiguration.javaからクラスWebConfiguration.javaと

@ComponentScan({ "com.subject", "com.custom" }) 

から

@ComponentScan(basePackages = { "com.controller", "com.service", "com.dao"}) 

を削除してみてください、そしてメインで単一

@ComponentScan(basePackages = { "com.controller", "com.service", "com.dao", "com.subject", "com.custom"}) 

とそれらを置き換えることができますSpringBootクラス?

関連する問題