2016-03-21 3 views
0

Я пытался создать REST API, прикрепленный с весной безопасностьюАннотации на основе Spring Security для REST API

Для деталей архитектуры любезно видеть эту ссылку: Spring Security with REST architecture

Но, во время моей реализации я столкнулся следующим такие вопросы, как:

Исключение запуска фильтра springSecurityFilterChain

Моя реализация приложений, как:

@EnableWebMvc 
@Configuration 
@ComponentScan({ "com.ws.service.*" }) 
public class AppConfig extends Application { 
... 
} 

CustomJDBCDaoImpl

public class CustomJDBCDaoImpl extends JdbcDaoImpl { 

    public CustomJDBCDaoImpl() { 
     // TODO Auto-generated constructor stub 
     super(); 

    } 

    private DataSource getDataSourceFromJndi() { 
     ... 
    } 

    @Override 
    protected List<GrantedAuthority> loadGroupAuthorities(String username) { 
    ... 
    } 

    @Override 
    public UserDetails loadUserByUsername(String username) { 
     ... 
    } 

    private UpUser findUserByScreenName(String userName) { 
     ... 
    } 

    private ResultSet executeQuery(String sql){ 
     ... 
    } 
} 

Source code for Stateless Authentication Filter

Stateless Authentication Security Config

@EnableWebSecurity 
@Configuration 
@Order(1) 
public class StatelessAuthenticationSecurityConfig extends WebSecurityConfigurerAdapter { 


    @Autowired 
    private TokenAuthenticationService tokenAuthenticationService; 

    public StatelessAuthenticationSecurityConfig() { 
     super(true); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .exceptionHandling().and() 
       .anonymous().and() 
       .servletApi().and() 
       .headers().cacheControl().and() 
       .authorizeRequests() 

       //allow anonymous resource requests 
       .antMatchers("/").permitAll() 
       .antMatchers("/favicon.ico").permitAll() 
       .antMatchers("/resources/**").permitAll() 

       //allow anonymous POSTs to login 
       .antMatchers(HttpMethod.POST, "/api/login").permitAll() 

       //allow anonymous GETs to API 
       .antMatchers(HttpMethod.GET, "/api/**").permitAll() 

       //defined Admin only API area 
       .antMatchers("/admin/**").hasRole("ADMIN") 

       //all other request need to be authenticated 
       .anyRequest().hasRole("USER").and()    

       // custom JSON based authentication by POST of {"username":"<name>","password":"<password>"} which sets the token header upon authentication 
       .addFilterBefore(new StatelessLoginFilter("/api/login", tokenAuthenticationService, new CustomJDBCDaoImpl(), authenticationManager()), UsernamePasswordAuthenticationFilter.class) 

       // custom Token based authentication based on the header previously given to the client 
       .addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class); 
    } 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

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


} 

Stateless Войти Фильтр

class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter { 

    private final TokenAuthenticationService tokenAuthenticationService; 
    private final CustomJDBCDaoImpl userDetailsService; 

    protected StatelessLoginFilter(String urlMapping, TokenAuthenticationService tokenAuthenticationService, 
      CustomJDBCDaoImpl userDetailsService, AuthenticationManager authManager) { 
     super(new AntPathRequestMatcher(urlMapping)); 
     this.userDetailsService = userDetailsService; 
     this.tokenAuthenticationService = tokenAuthenticationService; 
     setAuthenticationManager(authManager); 
    } 

    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) 
      throws AuthenticationException, IOException, ServletException { 

       final UsernamePasswordAuthenticationToken loginToken = new UsernamePasswordAuthenticationToken(
       request.getParameter("username").toString(), request.getParameter("password").toString()); 
     return getAuthenticationManager().authenticate(loginToken); 
    } 

    @Override 
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, 
      FilterChain chain, Authentication authentication) throws IOException, ServletException { 

     // Lookup the complete User object from the database and create an Authentication for it 
     final UserDetails authenticatedUser = userDetailsService.loadUserByUsername(authentication.getName()); 
     final UserAuthentication userAuthentication = new UserAuthentication(authenticatedUser); 

     // Add the custom token as HTTP header to the response 
     tokenAuthenticationService.addAuthentication(response, userAuthentication); 

     // Add the authentication to the Security context 
     SecurityContextHolder.getContext().setAuthentication(userAuthentication); 
    } 
} 

Source Code for Token Authentication Service

Source Code for Token Handler

Также он непосредственно перенаправляет меня на службу вместо того, чтобы показать мне диалоговое окно для ввода имени пользователя и пароля.

ответ

1

У меня есть аналогичные установки. разница, у меня есть дополнительный ContextLoaderListener для загрузки SpringSecurityFilerChain

@WebListener 
public class SpringContextLoader extends ContextLoaderListener { 

    @Override 
    protected WebApplicationContext createWebApplicationContext(final ServletContext sc) { 
     AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); 
     applicationContext.register(SpringConfiguration.class); 

     sc.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain")).addMappingForUrlPatterns(null, false, "/*"); 

     Dynamic dynamic = sc.addServlet("dispatcher", new DispatcherServlet(applicationContext)); 
     dynamic.addMapping("/"); 
     dynamic.setLoadOnStartup(1); 

     return applicationContext; 
    } 
} 
0

Можете ли вы попробовать настроить пакет проверки компонентов в файле Spring.xml или ApplicationContext.xml, если у вас есть этот файл. Также вы можете опубликовать трассировку стека ошибки.

Вам также может понадобиться настроить элемент filterChainProxy в весенне-security.xml и привязать его к URL шаблона, как/**

+0

Я не используя XML согласно моему описанию, я уже говорил, я использую конфигурацию –

+0

аннотаций на основе http://www.heypasteit.com/clip/2JB7 Исчерпывающая трассировка –

+0

Я видел пример, который использует как обработку XML, так и обработку аннотаций, если вы хотите ссылаться на http://www.mkyong.com/spring/spring-auto-wiring-beans-with-autowired-annotation/. Это работает, имея основные XML-записи, такие как пакет для сканирования и т. Д. В XML, а остальная часть конфигурации представлена ​​в виде аннотаций. – amitmah