2013-09-13 2 views
6

Использование аннотации и конфигурации java мне не совсем понятно, как зарегистрировать переопределенный фильтр для весенней безопасности.Фильтр аутентификации собственной безопасности Spring без web.xml

Что я хочу достичь, это сделать автоматический вход без отображения формы входа, так как в это время пользователь уже будет аутентифицирован. Поэтому будет только чтение параметра заголовка и использование весенней безопасности для авторизации.

Это упрощенная версия того, что я пытаюсь, и безопасность Spring работает правильно, за исключением того, что иногда отображается экран входа в систему. Загрузите BypassLoginFilter все, что мне нужно для этого. Также читайте где-то, что http auto config должен быть отключен для такого поведения, но не уверен, как реализовать в чистой конфигурации java.

SecurityWebApplicationInitializer.java

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; 

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer{ 

} 

SecurityConfig .java

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.builders.WebSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.web.authentication.logout.LogoutFilter; 

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

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/resources/**");  
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.csrf().disable(); 
     http.authorizeRequests().antMatchers("/*").permitAll() 
       .anyRequest().hasRole("USER").and() 
       .formLogin() 
       .permitAll(); 
     http.addFilterBefore(new BypassLoginFilter(), LogoutFilter.class); 
     //.and().anonymous().disable(); 
    } 

    @Override 
    @Autowired 
    protected void registerAuthentication(AuthenticationManagerBuilder auth) { 
     try { 
      auth.inMemoryAuthentication().withUser("user").password("password") 
      .roles("USER").and().withUser("admin").password("password") 
      .roles("USER", "ADMIN"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

BypassLoginFilter.java

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.springframework.security.core.Authentication; 
import org.springframework.security.core.AuthenticationException; 
import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.SimpleGrantedAuthority; 
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; 
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; 

public class BypassLoginFilter extends AbstractAuthenticationProcessingFilter{ 

    private static String HEADER_IS_ADMIN = "isAdmin"; 

    public BypassLoginFilter() 
    { 
     super("/*"); 
    } 

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

     boolean isAdmin = Boolean.valueOf(request.getHeader(HEADER_IS_ADMIN)); 

     PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken("","",getAuthorities(isAdmin)); 
     authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); 

     return getAuthenticationManager().authenticate(authRequest); 
    } 

    private List<GrantedAuthority> getAuthorities(boolean isAdmin) 
    { 
     List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 

     authorities.add(new SimpleGrantedAuthority("ROLE_USER")); 
     if(isAdmin){ 
      authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); 
     } 
     return authorities; 
    } 
} 
+1

Для начинающих Я бы ожидал, что ваш фильтр будет управляемым компонентом Spring. Теперь вы строите его самостоятельно. Добавьте аннотированный метод @Bean, который создает ваш фильтр. И не следует расширять его 'AbstractPreAuthenticatedProcessingFilter'. –

+0

@ M.Deinum, ваш ответ привел меня в правильном направлении. Добавлен компонент BypassLoginFilter, который теперь расширяет AbstractPreAuthenticatedProcessingFilter. Тем не менее, необходимо было настроить еще несколько компонентов для автопостановки. AuthenticationManager, PreAuthenticatedAuthenticationProvider и UserDetailsByNameServiceWrapper. Также отключена автоматическая настройка. –

ответ

0

Вы можете попробовать следующий подход. Скажем, у вас есть YourUser класс, который выглядит следующим образом:

public class YourUser extends org.springframework.security.core.userdetails.User{ 
    ... 
    public String getStartPage(){ return "/userhomepage"; } 
    ... 
} 

Затем вам нужно объявить обработчик аутентификации:

@Component 
public class YourAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { 

    protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) { 
     Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
     if (authentication.getPrincipal() instanceof YourUser) { 
      final YourUser user = (YourUser) authentication.getPrincipal(); 
      return user.getStartPage(); 
     }else { 
      return "/defaultPageForNonAuthenticatedUsers"; 
     } 
    } 
} 

и использовать его в конфигурации системы безопасности:

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     // rest calls are ommited 
     http.successHandler(successHandler()); 
    } 

    @Bean 
    public AuthenticationSuccessHandler successHandler() throws Exception { 
     return new YourAuthenticationSuccessHandler(); 
    } 
} 
Смежные вопросы