2014-12-16 20 views
27

Bir URL isteği parametresinde sağlanan şifreli bir belirteç kullanarak harici bir web hizmetine karşı kimlik doğrulaması yapmak için temel bir web uygulamasında Java yapılandırmasını kullanarak Spring Security uygulamasını yapılandırmaya çalışıyorum.Spring Config kullanarak özel güvenlik kimlik doğrulaması filtresi Configure

Oturum Açma Portalından gelen istekleri engelleyen bir güvenlik filtresine sahip olmak isterim (hepsi de/kimlik doğrulamasına gider), filtre kimlik doğrulama işleminin iş mantığını işlemek için bir AuthenticationProvider kullanır.

Oturum Aç Portal -> Yönlendirme '\ authenticate' (+ Token) -> Belirteç Girişini Portal'a Geri Döndür (WS) -> Başarı roller alır ve kullanıcıyı ayarlarsa. Ben bir filtre yarattık

..

@Component 
public final class OEWebTokenFilter extends GenericFilterBean { 
    @Override 
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { 
     if (request instanceof HttpServletRequest) { 
      OEToken token = extractToken(request); 
      // dump token into security context (for authentication-provider to pick up) 
      SecurityContextHolder.getContext().setAuthentication(token); 
     } 
    } 
    chain.doFilter(request, response); 
} 

Bir AuthenticationProvider ...

@Component 
public final class OEWebTokenAuthenticationProvider implements AuthenticationProvider { 
    @Autowired 
    private WebTokenService webTokenService; 

    @Override 
    public boolean supports(final Class<?> authentication) { 
     return OEWebToken.class.isAssignableFrom(authentication); 
    } 

    @Override 
    public Authentication authenticate(final Authentication authentication) { 
     if (!(authentication instanceof OEWebToken)) { 
      throw new AuthenticationServiceException("expecting a OEWebToken, got " + authentication); 
     } 

     try { 
      // validate token locally 
      OEWebToken token = (OEWebToken) authentication; 
      checkAccessToken(token); 

      // validate token remotely 
      webTokenService.validateToken(token); 

      // obtain user info from the token 
      User userFromToken = webTokenService.obtainUserInfo(token); 

      // obtain the user from the db 
      User userFromDB = userDao.findByUserName(userFromToken.getUsername()); 

      // validate the user status 
      checkUserStatus(userFromDB); 

      // update ncss db with values from OE 
      updateUserInDb(userFromToken, userFromDB); 

      // determine access rights 
      List<GrantedAuthority> roles = determineRoles(userFromDB); 

      // put account into security context (for controllers to use) 
      return new AuthenticatedAccount(userFromDB, roles); 
     } catch (AuthenticationException e) { 
      throw e; 
     } catch (Exception e) { 
      // stop non-AuthenticationExceptions. otherwise full stacktraces returned to the requester 
      throw new AuthenticationServiceException("Internal error occurred"); 
     } 
    } 

Ve Bahar Güvenlik Yapılandırma

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

    @Autowired 
    OESettings oeSettings; 

    @Bean(name="oeAuthenticationService") 
    public AuthenticationService oeAuthenticationService() throws AuthenticationServiceException { 
     return new AuthenticationServiceImpl(new OEAuthenticationServiceImpl(), oeSettings.getAuthenticateUrl(), oeSettings.getApplicationKey()); 
    } 

    @Autowired 
    private OEWebTokenFilter tokenFilter; 

    @Autowired 
    private OEWebTokenAuthenticationProvider tokenAuthenticationProvider; 

    @Autowired 
    private OEWebTokenEntryPoint tokenEntryPoint; 

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

    @Override 
    public void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(tokenAuthenticationProvider); 
    } 

    @Bean 
    public FilterRegistrationBean filterRegistrationBean() { 
     FilterRegistrationBean registrationBean = new FilterRegistrationBean();  
     registrationBean.setFilter(tokenFilter);  
     registrationBean.setEnabled(false); 
     return registrationBean; 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.csrf().disable() 
      .authorizeRequests() 
      .antMatchers("/authenticate**").permitAll() 
      .antMatchers("/resources/**").hasAuthority("ROLE_USER") 
      .antMatchers("/home**").hasAuthority("ROLE_USER") 
      .antMatchers("/personSearch**").hasAuthority("ROLE_ADMIN") 
      // Spring Boot actuator endpoints 
      .antMatchers("/autoconfig**").hasAuthority("ROLE_ADMIN") 
      .antMatchers("/beans**").hasAuthority("ROLE_ADMIN") 
      .antMatchers("/configprops**").hasAuthority("ROLE_ADMIN") 
      .antMatchers("/dump**").hasAuthority("ROLE_ADMIN") 
      .antMatchers("/env**").hasAuthority("ROLE_ADMIN") 
      .antMatchers("/health**").hasAuthority("ROLE_ADMIN") 
      .antMatchers("/info**").hasAuthority("ROLE_ADMIN") 
      .antMatchers("/mappings**").hasAuthority("ROLE_ADMIN") 
      .antMatchers("/metrics**").hasAuthority("ROLE_ADMIN") 
      .antMatchers("/trace**").hasAuthority("ROLE_ADMIN") 
      .and() 
       .addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class) 
       .authenticationProvider(tokenAuthenticationProvider) 
       .antMatcher("/authenticate/**") 
       .exceptionHandling().authenticationEntryPoint(tokenEntryPoint) 
      .and() 
       .logout().logoutSuccessUrl(oeSettings.getUrl()); 
    } 
} 

Benim sorunum filtresinin yapılandırması SpringConfig sınıfımda. Filtrenin yalnızca istek URL için/kimlik doğrulaması olduğunda devreye girmesini istiyorum. Filtre yapılandırmasına .antMatcher ("/ authenticate/**") ekledim. Artık sabitlenir, diğer tüm URL'lerin bu satırı varsa

.and() 
       .addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class) 
       .authenticationProvider(tokenAuthenticationProvider) 
       .antMatcher("/authenticate/**") 
       .exceptionHandling().authenticationEntryPoint(tokenEntryPoint) 

, el, kimlik doğrulaması yapmadan/home gidin satırını kaldırın ve/ev kimlik doğrulamasının olabilir.

Yalnızca belirli bir URL için geçerli bir filtre bildirmeli miyim?

Diğer URL'lerin güvenliğini korurken bunu nasıl uygularım? Kimlik doğrulama sağlayıcısı involking önce filtresinde kimlik doğrulama durumu hakkında bir çek gerçekleştirerek sorunumu çözdü ettik

+0

Teşekkür quetsion için. :) Yardım eder! – raj

cevap

12

....

Yapılandırma

.and() 
    .addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class) 
    .authenticationProvider(tokenAuthenticationProvider) 
    .exceptionHandling().authenticationEntryPoint(tokenEntryPoint) 

Filtre

@Override 
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) 
     throws IOException, ServletException { 

    logger.debug(this + "received authentication request from " + request.getRemoteHost() + " to " + request.getLocalName()); 

    if (request instanceof HttpServletRequest) { 
     if (isAuthenticationRequired()) { 
      // extract token from header 
      OEWebToken token = extractToken(request); 

      // dump token into security context (for authentication-provider to pick up) 
      SecurityContextHolder.getContext().setAuthentication(token); 
     } else { 
      logger.debug("session already contained valid Authentication - not checking again"); 
     } 
    } 

    chain.doFilter(request, response); 
} 

    private boolean isAuthenticationRequired() { 
    // apparently filters have to check this themselves. So make sure they have a proper AuthenticatedAccount in their session. 
    Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication(); 
    if ((existingAuth == null) || !existingAuth.isAuthenticated()) { 
     return true; 
    } 

    if (!(existingAuth instanceof AuthenticatedAccount)) { 
     return true; 
    } 

    // current session already authenticated 
    return false; 
} 
+4

Bu classess kodunu gönderebilirsiniz: "OEWebToken", "AuthenticatedAccount" ve "extractToken (request)" yöntem uygulaması? Dinlenme servisimle çok yardımcı olurum. Şimdiden teşekkürler. – masterdany88

İlgili konular