복붙노트

[SPRING] Spring 보안 jdbcAuthentication은 기본 롤 처리와 함께 작동하지 않습니다.

SPRING

Spring 보안 jdbcAuthentication은 기본 롤 처리와 함께 작동하지 않습니다.

사용

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
         auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");

내 예제가 잘 작동합니다. 예를 들어

      http.authorizeRequests()
        // ...
        .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
        .and().formLogin()
        .and().exceptionHandling().accessDeniedPage("/Access_Denied");

inMemoryAuthentication을 spring jdbc default로 변경 한 경우 -보다 중요한 역할을 맡았습니다.

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
         auth.jdbcAuthentication().dataSource(dataSource);

나는 봄 권장 사항 (기본 jdbc 인증을 사용할 수 있도록)을 사용하여 db와 스키마를 구성했다.

디버그 모드에서 나는 DB에서 로딩 결과를 볼 수 있습니다.

org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl
    #loadUserByUsername(username)[line 208]
    return createUserDetails(username, user, dbAuths);

메모리 구성에서 비슷한 결과를 반환합니다.

org.springframework.security.core.userdetails.User@183a3:
     Username: dba;
     Password: [PROTECTED];
     Enabled: true;
     AccountNonExpired: true;
     credentialsNonExpired: true;
     AccountNonLocked: true;
     Granted Authorities: ADMIN,DBA

볼 수 있듯이 부여 된 권한이로드되지만 http 요청은 .accessDeniedPage ( "/ Access_Denied")로 리디렉션됩니다. 이전처럼 사용자를 위해 작동해야하기 때문에 혼란 스러웠습니다.

나는 내 프로젝트에서 스프링 부트를 사용하지 않는다. 내 로그에 jdbc 오류 구성이 없습니다. 세부 사항을 조사하는 데 많은 시간을 할애했으며 아이디어는 끝났습니다. 일부 캐시 라이브러리 또는 다른 것을 만들기 위해 추가가 필요하다고 생각하십니까?

해결법

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

    1.여기에는 2 개의 잡화가 있습니다.

    여기에는 2 개의 잡화가 있습니다.

    첫 번째는 hasRole ( 'ADMIN')을 사용할 때 역할 접두사 (기본값은 ROLE_)로 시작하는 경우 먼저 확인이 수행되고 역할에 전달 된 접미사가 접두어가 아닌 경우 (참조 가이드 참조) . 따라서이 경우 실제 권한 검사는 ROLE_ADMIN이며 ADMIN은 예상 / 예상대로 수행하지 않습니다.

    두 번째는 in 메모리 옵션을 사용할 때 roles 메소드가 여기에 언급 된 것과 동일하다는 것입니다. 전달 된 역할이 역할 접두사로 시작하는지 확인하고, 추가하지 않으면 역할 접두어로 시작하는지 확인합니다. 따라서 메모리가있는 샘플에서 ROLE_ADMIN 및 ROLE_DBA 권한을 갖게됩니다.

    그러나 JDBC 옵션에서는 권한 ADMIN과 DBA가 있으므로 ROLE_ADMIN이 ADMIN이 아니기 때문에 hasRole ( 'ADMIN') 점검이 실패합니다.

    수정하려면 몇 가지 옵션이 있습니다.

    먼저 역할 대신 권한을 사용하도록 메모리 데이터베이스의 구성을 변경하십시오.

    auth.inMemoryAuthentication()
        .withUser("dba").password("root123")
        .authorities("ADMIN","DBA");
    

    다음으로 표현을 변경하십시오.

    .antMatchers("/db/**").access("hasAuthority('ADMIN') and hasAuthority('DBA')")
    

    권한을 삽입하는 스크립트에서 권한에 ROLE_ 접 두부가 붙습니다.

    이는 약간 까다 롭고 [이주 가이드]에서 광범위하게 설명됩니다.

    쉬운 구성 옵션이없고 BeanPostProcessor가 필요합니다.

    public class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
                throws BeansException {
    
            // remove this if you are not using JSR-250
            if(bean instanceof Jsr250MethodSecurityMetadataSource) {
                ((Jsr250MethodSecurityMetadataSource) bean).setDefaultRolePrefix(null);
            }
    
            if(bean instanceof DefaultMethodSecurityExpressionHandler) {
                ((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
            }
            if(bean instanceof DefaultWebSecurityExpressionHandler) {
                ((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
            }
            if(bean instanceof SecurityContextHolderAwareRequestFilter) {
                ((SecurityContextHolderAwareRequestFilter)bean).setRolePrefix("");
            }
            return bean;
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            return bean;
        }
    
        @Override
        public int getOrder() {
            return PriorityOrdered.HIGHEST_PRECEDENCE;
        }
    }
    
  2. ==============================

    2.로깅을 활성화 한 상황을 볼 수 있습니다. application.properties 파일에 다음을 추가하십시오.

    로깅을 활성화 한 상황을 볼 수 있습니다. application.properties 파일에 다음을 추가하십시오.

    # ==============================================================
    # = Logging springframework
    # ==============================================================
    logging.level.org.springframework.jdbc=DEBUG
    logging.level.org.springframework.security=DEBUG
    logging.level.org.springframework.web=DEBUG
    logging.level.org.springframework.http=DEBUG
    
  3. from https://stackoverflow.com/questions/35894206/spring-security-jdbcauthentication-does-not-work-with-default-roles-processing by cc-by-sa and MIT license