6

アノテーションと Java 構成を使用すると、Spring セキュリティ用にオーバーライドされたフィルターを登録する方法がよくわかりません。

私が達成したいのは、その時点でユーザーがすでに認証されているため、ログインフォームを表示せずに自動ログインを行うことです。したがって、ヘッダー パラメータのみを読み取り、認証目的でスプリング セキュリティを使用します。

これは私がやろうとしていることの単純化されたバージョンであり、ログイン画面を時々表示することを除いて、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;
    }
}
4

1 に答える 1

1

次のアプローチを試すことができます。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();
    }
}
于 2015-03-02T14:05:47.903 に答える