복붙노트

[SPRING] 스프링 보안 - 요청 매개 변수가있는 URL은 무시됩니다.

SPRING

스프링 보안 - 요청 매개 변수가있는 URL은 무시됩니다.

봄 보안을 사용하는 웹 애플리케이션이 있습니다. 요소를 사용하여 다른 URL에 대한 액세스 필터를 설명합니다. 기본적으로이 매개 변수는 요청 URL 매개 변수를 고려하지 않습니다. 요청 매개 변수를 기반으로 URL의 사용자 지정 보안 규칙을 설정해야했습니다. 그래서 다음과 같이했습니다.

1) 스프링 보안 메카니즘을위한 요청 매개 변수 옵션을 가능하게하는 bean post-processor 클래스를 만들었습니다 :

<beans:beans>
    . . .
    <beans:bean class="MySecurityBeanPostProcessor">
        <beans:property name="stripQueryStringFromUrls" value="false" />
    </beans:bean>
    . . .
</beans:beans>

그리고 코드 :

public class MySecurityBeanPostProcessor implements BeanPostProcessor {

    private Boolean stripQueryStringFromUrls = null;

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof DefaultFilterInvocationSecurityMetadataSource && stripQueryStringFromUrls != null) {
            ((DefaultFilterInvocationSecurityMetadataSource) bean)
                .setStripQueryStringFromUrls(stripQueryStringFromUrls.booleanValue());
        }
        return bean;
    }

    // code stripped for clarity
}

이렇게하면 요청 매개 변수를 고려하여 스프링 보안 메타 데이터 소스를 설정해야합니다. 위 코드를 디버깅했으며 stripQueryStringFromUrls 속성이 설정되었습니다.

2) 내 보안 컨텍스트 xml에는 다음과 같은 정의가 있습니다.

<intercept-url pattern="/myUrl?param=value" access="!isAuthenticated() or hasRole('ROLE_GUEST')" />
<intercept-url pattern="/myUrl" filters="none" />
...
<intercept-url pattern="/**" access="isAuthenticated()" />

보시다시피, 사용자가 인증되지 않았거나 게스트 계정을 사용하는 경우에만 지정된 매개 변수를 사용하여 URL에 액세스해야합니다. 또한 동일한 URL에 대한 규칙을 추가했지만 필터가없는 모든 매개 변수는 추가하지 않았습니다.

내가 아는 한, 봄 보안은 특정 적이지기 전에 더 구체적인 URL을 제공하도록 구성되어야한다. 그렇지 않으면 체인이 더 일반적인 규칙을 먼저 감지하고 더 구체적으로 진행하지 않을 것이기 때문이다. 그래서 params를 사용하는 url이보다 구체적인 것으로 기대되어 인증되지 않은 비 게스트 사용자의 액세스가 거부됩니다. 대신, 아래에 정의 된보다 일반적인 규칙이 적용됩니다. 출력은 다음과 같습니다.

나는 또한 매개 변수가없는 url에 대한 규칙을 삭제하려고 시도했다. 그런 다음 매개 변수가있는 url에 대한 내 규칙을 적용하는 대신 필터는 / ** 패턴을 선택하고 사용자가 로그인해야합니다. 그것에 대한 결과는 다음과 같습니다.

이 응용 프로그램은 Java 1.6으로 작성되었으며 Spring v3.0을 사용하며 Linux 시스템의 JBoss v5.1.0-GA에 배포됩니다. 필자는 설명 된 방식으로 필터가 작동하는 이유에 대한 단서가 없습니다. 귀하의 도움과 조언을 대단히 감사하겠습니다.

편집하다:

결론적으로, 내가 관찰 한 것은 / myUrl? param = value 필터가 결코 적용되지 않는다는 것인데, 마치 security-context.xml의 엔트리가 무시 된 것처럼 말이다. 이것은 내가 지금까지 관찰 한 행동에 적합합니다. 나는 또한 필터 = "none"을 access = "permitAll"로 바꾸고, regex로 바꾸었다. (예를 들어 / myUrl? param = value는 \ A / myUrl \? param = value \ Z가된다. 유사 콘텐츠는 내가받는 행동이 동일합니다.

편집 2 :

여기에 설명 된 문제는 실제로 유효하지 않습니다. 그 이유는 다음과 같습니다. 문제가있는 프로젝트는 내부 라이브러리 충돌 및 비 호환성으로 인해 일부 봄 패키지를 제외 시켰지만 전체 설치가 어떻게 든 작동했습니다. 나는 그 사실을 전혀 알지 못했고 실제로이 굳건한 구성이 전체 질문을 쓸데없는 것으로 만듭니다. 구체적인 이유는 isAuthenticated () 및 isAnonymous () 메서드의 구현이 예상대로 작동하지 않아 여기에 제공된 모든 조언이 작동하지 않는다는 것입니다.

해결법

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

    1.Spring Security 3.0에서는 filters = "none"을 사용하면 빈 필터 목록이있는 패턴을 FilterChainProxy에 추가하는 반면, 액세스 속성을 사용하면 보안 액세스 규칙이 다음과 같이 변경된다는 공통적 인 혼란이 있습니다. URL를 보호하기 위해 사용되는 FilterSecurityInterceptor

    Spring Security 3.0에서는 filters = "none"을 사용하면 빈 필터 목록이있는 패턴을 FilterChainProxy에 추가하는 반면, 액세스 속성을 사용하면 보안 액세스 규칙이 다음과 같이 변경된다는 공통적 인 혼란이 있습니다. URL를 보호하기 위해 사용되는 FilterSecurityInterceptor

    일치 프로세스는 다음과 같습니다.

    두 클래스 모두 정의 된 순서대로 적용되는 정렬 된 정렬 자 목록을 유지하지만 그 아래에는 직접 연결된 두 개의 별도 bean이 구성되어 있다는 것을 이해해야합니다.

    간단한 네임 스페이스 애플리케이션에서 블록은 / ** 패턴을 사용하여 FilterChainProxy에 단일 필터 체인을 추가합니다. 추가 한 모든 filters = "none"패턴은 실제 체인 앞에 빈 필터 체인을 배치합니다.

    Spring 보안 3.1에서는 상황이 더욱 개선되었습니다. 별도의 블록을 사용하여 별도의 필터 체인을 구성합니다.이 블록은 실제로 콩 수준에서 발생하는 상황에보다 직관적으로 매핑됩니다. 요청 일치 프로세스도 많이 개선되어 이제 모든 것을 위해 RequestMatcher 인터페이스를 사용합니다. 블록을 구성 할 때 패턴 대신이 값을 사용할 수도 있습니다.

    따라서 가장 좋은 옵션은 업그레이드하는 것입니다. 그런 다음 MyParamRequestMatcher라고 말한 찾고있는 매개 변수의 존재를 확인하는 RequestMatcher를 구현 한 다음 다음을 사용할 수 있습니다.

    <http request-matcher-ref="myParamMatcher" security="none" />
    
    <bean:bean id="myParamMatcher" class="MyParamRequestMatcher" />
    
    <http>
        <!-- Define the default filter chain configuration here -->
    </http>
    

    URL 패턴을 사용하여 매개 변수를 일치시키는 것은 일반적으로 URL의 순서를 변경하고 가짜 패턴을 추가하여 우회하기 쉽기 때문에 일반적으로 매우 안전하지는 않습니다. 매개 변수가있는 버전은 보안되지 않은 액세스를 허용하고 다른 경우에는 인증을 요구하는 패턴을 가지고 있기 때문에 귀하의 사례는 아마 괜찮습니다.

    3.0에 머 무르려면 가장 좋은 방법은 filters = "none"(isAnonymous ()를 대신 사용)을 피하고 ant 경로가 아닌 정규식 일치를 사용하여 쿼리 문자열을보다 쉽게 ​​일치시킬 수 있도록하는 것입니다. 다시 말하면이 방법으로 정의 된 규칙을 거의 무시할 수 있다는 것을 반복해야합니다. 따라서 더 많은 보안을 위해 의존하지 말고 기본적으로 안전하다는 것을 확인하십시오.

    regex matching과 permitAll을 사용하는 것에 대한 제안으로서, Spring Security의 3.0.x 브랜치에서 "튜토리얼"샘플 애플리케이션을 수정하면 다음과 같다.

    <http use-expressions="true" path-type="regex">
        <intercept-url pattern="\A/secure/extreme/.*\Z" access="hasRole('ROLE_SUPERVISOR')"/>
        <intercept-url pattern="\A/secure/index.jsp\?param=value\Z" access="permitAll" />
        <intercept-url pattern="\A/secure/.*\Z" access="isAuthenticated()" />
        <intercept-url pattern="/.*" access="permitAll" />
        ...
    </http>
    

    그런 다음 예상되는 동작을 얻습니다.

    [DEBUG,FilterChainProxy] Candidate is: '/secure/index.jsp?param=value'; pattern is /.*; matched=true
    [DEBUG,FilterChainProxy] /secure/index.jsp?param=value at position 1 of 12 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
    ...
    [DEBUG,FilterChainProxy] /secure/index.jsp?param=value at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
    [DEBUG,FilterChainProxy] /secure/index.jsp?param=value at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
    [DEBUG,ExpressionBasedFilterInvocationSecurityMetadataSource] Candidate is: '/secure/index.jsp?param=value'; pattern is \A/secure/extreme/.*\Z; matched=false
    [DEBUG,ExpressionBasedFilterInvocationSecurityMetadataSource] Candidate is: '/secure/index.jsp?param=value'; pattern is \A/secure/index.jsp\?param=value\Z; matched=true
    [DEBUG,FilterSecurityInterceptor] Secure object: FilterInvocation: URL: /secure/index.jsp?param=value; Attributes: [permitAll]
    

    . * 아래에 일치하는 FilterChainProxy와 정확한 URL을 매개 변수와 일치시키는 FilterSecurityInterceptor가 표시됩니다.

  2. from https://stackoverflow.com/questions/8908052/spring-security-url-with-request-parameters-rules-ignored by cc-by-sa and MIT license