두 세트의 URL이 있습니다. 한 세트는 REST API이고, 두 번째 세트는 꽤 일반적인 웹 사이트입니다. 가끔씩 REST API를 호출하는 사용자/스크립트가 401 코드 (기본 인증은 괜찮을 수 있음) 또는 403에만 응답하도록 REST API에 대해 다른 보안 규칙을 적용하려고합니다.스프링 보안 - REST API 및 다른 URL에 대한 별도의 구성
그래서 허용하고 싶습니다. 다음에 대한 REST API 액세스 :
- 로그인 한 사용자 (REST API를 호출하는 사이트 페이지의 javascript는 동일한 세션을 공유 함).
- WWW-Authenticate 헤더에서 기본 인증 자격 증명으로 REST API를 호출하는 일부 스크립트.
현재 스프링이 내가 원하는 것을 "이해하게"만드는 구성을 파악하려고합니다. 나는 다음과 같은 설정 내놓았다 :
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/" security="none" />
<http pattern="/static/**" security="none" />
<!-- REST API -->
<http pattern="/rest/*" use-expressions="true">
<http-basic />
<intercept-url pattern="/*" access="isAuthenticated()" />
</http>
<!-- Site -->
<http access-denied-page="/WEB-INF/views/errors/403.jsp" use-expressions="true">
<intercept-url pattern="/index.html" access="hasRole('ROLE_USER') or hasRole('ROLE_ANONYMOUS')" />
<intercept-url pattern="/login.html" access="hasRole('ROLE_USER') or hasRole('ROLE_ANONYMOUS')" />
<intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/login.html"
default-target-url="/index.html"
authentication-failure-url="/login.html?error=1" />
<logout logout-url="/logout.do" logout-success-url="/index.html" />
<anonymous username="guest" granted-authority="ROLE_ANONYMOUS" />
<remember-me />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="2" authorities="ROLE_ADMIN,ROLE_USER" />
<user name="alex" password="1" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
불행하게도뿐만 아니라 기본 인증이 설정 작동하지 않습니다하지만 거기에는 403 개 익명 사용자에 의해 요청에 대한 응답이 없습니다 - 찾을 수 리디렉션 (302)와 응용 프로그램이 응답하는 내가 좋겠 REST API URL을 허용하지 않으려면
<beans:bean id="ep403" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<!-- REST API -->
<http pattern="/rest/*" entry-point-ref="ep403" use-expressions="true">
<intercept-url pattern="/*" access="hasRole('ROLE_USER')" />
<http-basic />
</http>
을하지만이 중 하나가 작동하지 않습니다
나는 REST API에 대한 사용자 정의 진입 점을 추가했습니다.
내가하고 싶지 않은 것을 요약하면 :- 은 (인증 기능 계정으로 쿠키를 사용자 세션을해야) 권한이 부여 된 사용자가 REST API에 액세스 할 수 있도록 허용합니다.
- 올바른 인증 토큰을 지정하고 쿠키에 세션을 지정하지 않으면 스크립트가 REST API에 액세스하도록 허용합니다.
UPDATE
봄 보안 내부로 파고 후 나는 특정 요청 또는하지를 거부할지 여부를 결정하는 코드를 발견했다. 이것은 소위 말하는 "Access Decision Voters"입니다. 기본적으로 모든 요청은 특정 요청에 적용되며 체인에있는 한 명의 액세스 결정 유권자가 특정 리소스에 대한 액세스를 거부하도록 투표하면 최종적으로 요청이 거부됩니다.
따라서 원래의 문제는 다음과 같은 방식으로 동작하는 특수 액세스 결정 투표자를 도입하여 해결할 수 있습니다. 세션에서 관련 역할을 추출하려고 시도하면 (요청에있는 경우)이 역할로 승인 단계로 진행합니다. 세션이 존재하지 않으면 WWW-Authenticate 헤더의 자격 증명에 대해 사용자를 인증하려고 시도한 다음 지정된 사용자와 관련된 역할로 인증 단계로 진행합니다.
create-session이 트릭을 수행하지만, 기본 인증 작업을 세션별로 인증하지 못하게합니다. 즉, 페이지의 javascript가 REST API에 액세스 할 수 없습니다. – Alex
네, 맞습니다. 패턴을 바꾸는 것이 도움이 되었습니까? –
패턴에는 별다른 영향이 없습니다. 이제는 매우 간단한 REST API URL 스키마가 있습니다 (예 :/rest/book? name = X - 인증로드가 걸리면 확장 할 생각이 아닙니다) . 물론 내 패턴은/rest/one/two와 같이 깊은 네 스팅이있는 URL에서는 작동하지 않을 것이므로이를 지적 해 주셔서 감사합니다. create-session = "stateless"는 두 패턴 모두에 대해 기본적인 인증 작업을하지만 스프링이 두 패턴에 대해서도 기존의 인증 된 세션을 무시하게 만듭니다. – Alex