복붙노트

[SPRING] 커스텀 userdetailsservice를위한 bean 정의하기

SPRING

커스텀 userdetailsservice를위한 bean 정의하기

내 봄 mvc 웹 응용 프로그램이 내 기본 MySQL 데이터베이스를 사용하여 사용자 및 비밀번호 인증을 확인할 수 있도록 사용자 정의 UserDetailsService bean을 정의하는 방법은 무엇입니까?

구체적인 내용은 다음과 같습니다.

스프링 보안에 대해 배우는 방법으로 봄 Petclinic 샘플에 보안을 추가합니다. Java 구성을 사용 중이고 WebSecurityConfigurerAdapter를 확장하는 SecurityConfig.java 파일을 설정했습니다. 나는 petclinic 샘플에 내장 된 ClinicService 도구에 의해 관리되는 MySQL 데이터베이스를 사용하는 방식으로 JdbcAuthentication을 설정하려고합니다. 따라서 UserDetailsService를 확장하고 CustomConnection.java와 ClinicService.java를 연결하기위한 CustomUserDetailsService 클래스를 만들었습니다. User 클래스와 Role 클래스를 만들어 MySQL 데이터베이스에서 사용자와 역할 테이블을 각각 모델링했습니다.

그런 다음 business-config.xml에 다음 줄을 추가하여 CustomUserDetailService를 정의했습니다.

<bean class="org.springframework.samples.petclinic.service.CustomUserDetailsService"></bean>

그러나 여전히 CustomUserDetailService에 대한 bean이 정의되지 않았다는 다음 오류가 계속 발생합니다.

Caused by: java.lang.IllegalArgumentException: Can not set  
org.springframework.samples.petclinic.service.CustomUserDetailsService field  
org.springframework.security.samples.petclinic.config.SecurityConfig.myCustomUserDetailsService  
to $Proxy61

이 게시를 간결하게 유지하기 위해 관련 백업 자료를 파일 공유 사이트에로드했습니다. 다음 링크를 클릭하면 모든 소스 코드와 전체 스택 추적을 읽을 수 있습니다.

이 링크를 클릭하면 SecurityConfig.java를 읽을 수 있습니다. business-config.xml의 코드는이 링크에 있습니다. CustomUserDetailService.java의 코드는이 링크에 있습니다. User 엔티티의 코드는이 링크에 있습니다. 역할 엔티티의 코드는이 링크에 있습니다. 전체 스택 추적은이 링크에서 읽을 수 있습니다.

응용 프로그램의 다른 모든 코드는 Spring petclinic 샘플의 github 페이지에서 찾을 수 있습니다.이 링크는이 링크를 클릭하여 읽을 수 있습니다.

다음은 login.jsp의 코드에 대한 링크입니다.

다음은 수정 된 business-config.xml 코드에 대한 링크입니다.

해결법

  1. ==============================

    1.주석을 요약하면 다음과 같습니다.

    주석을 요약하면 다음과 같습니다.

    여기 몇 가지 잘못된 점이 있습니다.

    1) Spring에서 XML 설정과 Java 설정을 XML 설정 파일 내부로 가져 오는 방식으로 가 xml 파일에 존재해야하고 자바 설정 클래스를 Bean으로 선언해야한다. . 는 선언 된 bean의 주석 처리를 가능하게 할 것이고 @Configuration annotation은 처리 될 것입니다. 자세한 내용은 http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-java-combining을 참조하십시오.

    문제를 해결하려면 business-config.xml에 를 삽입하십시오. 가 동일한 bean 프로파일에서 선언 될 필요가 있기 때문에 가 필요합니다.

    2) 인터페이스 (UserDetailsService) 대신 SpringConfig에서 구체적인 클래스 (CustomUserDetailsSerivce)를 autowiring하고 있습니다. Spring을 사용하여 구체적인 클래스를 자동으로 호출하는 것이 가능하지만 인터페이스에 자동으로 연결하는 것이 더 좋습니다 (Spring은 CustomUserDetailsService 구현을 @Autowired UserDetailsService 필드로 자동 변환합니다). Spring은 특정 기능 (예 : 선언적 트랜잭션)을 가능하게하기 위해 유선 클래스 주위에 프록시를 생성하며, 그러한 프록시는 자동 와이어 링시 인터페이스를 쉽게 구현할 수 있지만 구체적인 클래스에 자동 연결하려고 시도하면 실패 할 수 있습니다. 그것은 가능합니다 - 더 많은 정보는 여기를 : Spring Autowiring 클래스 대 인터페이스? 이 경우, 우리의 보안 설정이 실제로 의존하는 것이므로 UserDetailsService 인터페이스에 자동으로 연결하는 것이 좋습니다.

    이 문제를 해결하려면 SpringConfig에서 필드 유형을 UserDetailsService로 지정하십시오.

    //Use UseDetailsService interface as field type instead of concrete class CustomUserDao
    @Autowired
    private UserDetailsService myCustomUserDetailsService;
    

    3) 사용자 정의 사용자 세부 사항 서비스를 사용하여 jdbc 인증 및 인증을 설정하는 것 같습니다. 스프링 JDBC 인증은 보통 Spring Security가 jdbc를 사용하여 데이터베이스를 질의하고 기존 사용자와 그 역할 등을 찾길 원할 때 사용됩니다 ... 사용자 / 역할 등에 대한 쿼리 구현을 원한다면 사용자 정의 UserDetailsSerivce가 사용됩니다. 귀하의 예 (ClinicService를 사용하여 백엔드를 쿼리 할 사용자 정의 UserDetailsService를 제공하고 있기 때문에)에서는 JDBC 인증이 필요하지 않습니다.

    다음은 java config를 통해 사용자 정의 UserDetailsService (다른 곳에서 구현되고 봄에 autowired)를 사용하는 스프링 보안 구성 작업의 예입니다.

    @Configuration
    @EnableWebMvcSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private UserDetailsService userDetailsService;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .formLogin()
                    .loginPage("/login")
                    .defaultSuccessUrl("/petclinic/")
                    .usernameParameter("j_username") // default is username
                    .passwordParameter("j_password") // default is password
                    .loginProcessingUrl("/j_spring_security_check") // default is /login with an HTTP post 
                    .failureUrl("/login")
                    .permitAll()
                    .and()
                .logout()
                    .logoutSuccessUrl("/index.jsp")
                    .and()
                .authorizeRequests()
                    .antMatchers("/**").hasRole("ROLE_ADMIN")
                    .antMatchers("/j_spring_security_check").permitAll()
                    .and()
                .userDetailsService(userDetailsService);
        }
    }
    

    특정 구성 빌더 메소드가 수행하는 작업을 설명하고 예제를 제공하면서 실제 문서를 읽는 것이 좋습니다. http://docs.spring.io/spring-security/site/docs/3.2.0.RC2/apidocs/org/springframework/ security / config / annotation / web / builers / HttpSecurity.html # formLogin ()

    편집 1 - 로그인 양식 구성 및 문서 링크 추가

    편집 2 - 문제에 대한 자세한 설명 추가 1)

    수정 3 - UserNameServiceService의 역할 이름과 일치하도록 역할 이름 양식 "ADMIN"을 "ROLE_ADMiN"으로 변경했습니다.

  2. from https://stackoverflow.com/questions/22750241/defining-bean-for-custom-userdetailsservice by cc-by-sa and MIT license