2

HTTP 基本認証で保護されたいくつかのリソースを必要とする簡単な REST アプリがあります。このアプリのクライアントが行う可能性のある何かに応答して、コンテナーによって生成された HTML を見たくありません。したがって、SpringSecurity を次のようにセットアップしました。

<http pattern="/api/**" auto-config="true" create-session="stateless" entry-point-ref="entryPoint">
    <intercept-url pattern="/**" method="PUT" access="ROLE_ADMIN" />
    <intercept-url pattern="/**" method="POST" access="ROLE_ADMIN" />
    <intercept-url pattern="/**" method="DELETE" access="ROLE_ADMIN" />
    <http-basic />
</http>

<http security="none" />

<authentication-manager>
    <authentication-provider>
        <user-service id="userDetailsService" 
            properties="classpath:META-INF/spring/users.properties"/>
    </authentication-provider>
</authentication-manager>

私の EntryPoint クラスは次のようになります。

public class BasicJsonEntryPoint extends BasicAuthenticationEntryPoint {

    @Override
    public void commence(
        HttpServletRequest request, 
        HttpServletResponse response, 
        AuthenticationException authException
    ) throws IOException, ServletException {

        response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\"");
        response.setStatus(SC_UNAUTHORIZED);
        PrintWriter writer = response.getWriter();
        writer.println("{\"status\":" + SC_UNAUTHORIZED + ", \"message\":\"" + authException.getMessage() + "\"}");

    }
}

これは、保護されたリソース/メソッドの組み合わせにヒットしたときに機能し、次のような結果が得られます。

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
WWW-Authenticate: Basic realm="Admin"
Content-Length: 84
Date: Sun, 29 Sep 2013 11:50:48 GMT

{"status":401, "message":"Full authentication is required to access this resource"}

..まさに私が欲しいものです。ただし、Authorize: HTTP ヘッダーで無効な資格情報を指定すると、Tomcat の HTML 応答が返されます...

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
WWW-Authenticate: Basic realm="Admin"
Content-Type: text/html;charset=utf-8
Content-Length: 1019
Date: Sun, 29 Sep 2013 11:51:14 GMT

<html><head><title>Apache Tomcat/7.0.33 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - Invalid basic authentication token</h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u>Invalid basic authentication token</u></p><p><b>description</b> <u>This request requires HTTP authentication.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.33</h3></body></html>

ここで同じ JSON 応答を取得するには、他に何をオーバーライド/実装する必要がありますか (理想的には、既に作成した同じクラスを使用します)。

どうもありがとう、

4

1 に答える 1

2

問題は、実装の代わりにBasicAuthenticationFilter独自のインスタンスを使用している にあります。BasicAuthenticationEntryPointしたがって、少し調整できます。

<http auto-config="true" create-session="stateless">
    <intercept-url .../>
    <http-basic />
    <custom-filter ref="basicAuthenticationFilter" before="BASIC_AUTH_FILTER" />
</http>

<beans:bean id="basicAuthenticationFilter"
      class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
    <beans:property name="authenticationManager" ref="authenticationManager" />
    <beans:property name="authenticationEntryPoint" ref="entryPoint" />
</beans:bean>

<beans:bean id="entryPoint" class="mypackage.BasicJsonEntryPoint">
    <beans:property name="realmName" value="realm"/>
</beans:bean>

<authentication-manager alias="authenticationManager">
    <authentication-provider>
        ...
    </authentication-provider>
</authentication-manager>
于 2013-09-30T20:50:35.703 に答える