Özel Bir Filtrede Java Yapılandırmasını Kullanarak AuthenticationManager Nasıl Enjekte Edilir


81

Spring Security 3.2 ve Spring 4.0.1 kullanıyorum

Bir xml yapılandırmasını Java yapılandırmasına dönüştürmeye çalışıyorum. Filtremde AuthenticationManagerile açıklama @Autowiredyaptığımda, bir istisna alıyorum

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

Enjekte etmeyi denedim AuthenticationManagerFactoryBeanama bu da benzer bir istisna dışında başarısız oluyor.

İşte çalıştığım XML yapılandırması

<?xml version="1.0" encoding="UTF-8"?> <beans ...>
    <security:authentication-manager id="authenticationManager">
        <security:authentication-provider user-service-ref="userDao">
            <security:password-encoder ref="passwordEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>

    <security:http
            realm="Protected API"
            use-expressions="true"
            auto-config="false"
            create-session="stateless"
            entry-point-ref="unauthorizedEntryPoint"
            authentication-manager-ref="authenticationManager">
        <security:access-denied-handler ref="accessDeniedHandler"/>
        <security:custom-filter ref="tokenAuthenticationProcessingFilter" position="FORM_LOGIN_FILTER"/>
        <security:custom-filter ref="tokenFilter" position="REMEMBER_ME_FILTER"/>
        <security:intercept-url method="GET" pattern="/rest/news/**" access="hasRole('user')"/>
        <security:intercept-url method="PUT" pattern="/rest/news/**" access="hasRole('admin')"/>
        <security:intercept-url method="POST" pattern="/rest/news/**" access="hasRole('admin')"/>
        <security:intercept-url method="DELETE" pattern="/rest/news/**" access="hasRole('admin')"/>
    </security:http>

    <bean class="com.unsubcentral.security.TokenAuthenticationProcessingFilter"
          id="tokenAuthenticationProcessingFilter">
        <constructor-arg value="/rest/user/authenticate"/>
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
        <property name="authenticationFailureHandler" ref="authenticationFailureHandler"/>
    </bean>

</beans>

İşte denediğim Java Yapılandırması

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private AccessDeniedHandler accessDeniedHandler;

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                .exceptionHandling()
                    .authenticationEntryPoint(authenticationEntryPoint)
                    .accessDeniedHandler(accessDeniedHandler)
                    .and();
        //TODO: Custom Filters
    }
}

Ve bu, Özel Filtre sınıfıdır. Bana sorun çıkaran satır, AuthenticationManager için belirleyici.

@Component
public class TokenAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {


    @Autowired
    public TokenAuthenticationProcessingFilter(@Value("/rest/useAuthenticationManagerr/authenticate") String defaultFilterProcessesUrl) {
        super(defaultFilterProcessesUrl);
    }


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

    private String obtainPassword(HttpServletRequest request) {
        return request.getParameter("password");
    }

    private String obtainUsername(HttpServletRequest request) {
        return request.getParameter("username");
    }

    @Autowired
    @Override
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
    }

    @Autowired
    @Override
    public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
        super.setAuthenticationSuccessHandler(successHandler);
    }

    @Autowired
    @Override
    public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
        super.setAuthenticationFailureHandler(failureHandler);
    }
}

Otomatik Kablolamanın bir Geçersiz Kılmanın hemen üzerinde ne yaptığını sorabilir miyim? Bunu daha önce hiç görmedim. Bununla ne bağlantılı?
Stephane

Özel filtrenizi nasıl eklediniz? Kendi filtremi ve Kimlik doğrulama sağlayıcımı yaptım. Ama onları birlikte çalışacak şekilde nasıl yapılandıracağımı bilmiyorum. Sorum şu: stackoverflow.com/questions/30502589/…
PaintedRed

Yanıtlar:


190

Yöntemini geçersiz kılar authenticationManagerBeaniçinde WebSecurityConfigurerAdapterAuthenticationManager kullanılarak inşa ortaya çıkarmak için configure(AuthenticationManagerBuilder)bir bahar fasulyesi:

Örneğin:

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

1
@qxixp "configure (AuthenticationManagerBuilder) kullanılarak oluşturulan AuthenticationManager'ı Spring Bean olarak ortaya çıkarmak için"
Roger

1
@Roger, AuthenticationManager'ı neden manuel olarak göstermemiz gerekiyor?
qxixp

11
@qxixp Yalnızca yayla yönetilen bir fasulyeyi Autowire yapabilirsiniz. Fasulye olarak açığa çıkmamışsa, Otomatik Kablolama yapamazsınız.
Roger

Süper yöntem Bean değildir, ardından Geçersiz kılın ve Bean ek açıklaması ekleyin.
searching9x

2
Bu yanıtta bana gerçekten yardımcı olan şey "name = BeanIds.AUTHENTICATION_MANAGER" oldu. Onsuz, en azından benim çevremde çalışmıyor.
Isthar

1

Angular University'nin yukarıda söylediklerine ek olarak, @Configuration sınıflarını diğer sınıfta toplamak için @Import kullanmak isteyebilirsiniz (benim durumumda AuthenticationController):

@Import(SecurityConfig.class)
@RestController
public class AuthenticationController {
@Autowired
private AuthenticationManager authenticationManager;
//some logic
}

@Yapılandırma sınıflarını @ Import ile Toplama hakkında bahar dokümanı: link

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.