2013-09-30 3 views
2

У меня есть тривиальное приложение REST, которому требуется несколько ресурсов, защищенных с помощью HTTP Basic auth. Я никогда не хочу видеть созданный контейнером HTML в ответ на все, что может сделать клиент этого приложения. Так что у меня установка мой SpringSecurity так:Переопределение ответа контейнера для весенней безопасности BadCredentialsException

<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"} 

.. что именно то, что я хочу. Однако, если я поставляю недействительны в авторизовать: HTTP заголовок, я получаю HTML ответ приложения Tomcat ...

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 здесь (в идеале, используя тот же класс, который я уже создал)?

Большое спасибо,

ответ

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> 
+0

Спасибо! Я обнаружил, что мне нужно сохранить элемент [entry-point-ref = "entryPoint"] в элементе , чтобы исходный запрос без учетных данных все еще работал. – darrend

Смежные вопросы