如何为未经授权的AJAX调用返回JSON响应,而不是作为AJAX响应返回登录页面? [英] How to return JSON response for unauthorized AJAX calls instead of login page as AJAX response?

查看:94
本文介绍了如何为未经授权的AJAX调用返回JSON响应,而不是作为AJAX响应返回登录页面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在我的应用程序中实现了Spring Security。如果有人要求对这些URL进行身份验证,则只要有人尝试访问任何URL,都会将用户重定向到登录页面。现在,如果对任何此类URL进行AJAX调用,我想返回JSON响应,而不是登录页面的HTML作为AJAX响应。我该怎么办?

I have implemented Spring Security in my application. Whenever someone tries to access any url if authentication is required for these urls user will be redirected to login page. Now, if AJAX call is made for any such url I would like to return JSON response instead of login page's HTML as AJAX response. How can I do that ?

推荐答案

不久前面对同样的事情,提出了这种解决方案。

Faced the same thing not long ago, came out with this solution.

您必须重新定义身份验证入口点以处理异常并返回正确的JSON响应。

You'll have to redefine the authentication entry point to handle the exception and returning a proper JSON response.

首先创建一个类您的回应。需要成为POJO。

First create a class for your response. Needs to be a POJO.

public class MyErrorResponse {
    // your stuff here, and getters / setters
}

然后定义身份验证入口点

Then go define the authentication entry point

public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {

    private List<HttpMessageConverter<Object>> messageConverters = new ArrayList<>();

    private MediaType retrieveRequestMediaType(HttpServletRequest request) {
        String accept = request.getHeader("accept");

        if(Strings.isNullOrEmpty(accept))
            accept = MediaType.APPLICATION_JSON_VALUE;

        MediaType requestMediaType = MediaType.valueOf(accept);

        return requestMediaType;
    }

    private HttpMessageConverter<Object> retrieveMessageConverter(List<HttpMessageConverter<Object>> messageConverters, Class<?> clazz, MediaType mediaType) {
        for (HttpMessageConverter<Object> httpMessageConverter : messageConverters) {
            if(httpMessageConverter.canWrite(clazz, mediaType)) {
                return httpMessageConverter;
            }
        }
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        log.warn(String.format("Unauthorized access with session id '%s'", request.getSession().getId()));

        MyErrorResponse esponse = new MyErrorResponse();
        // populate your response object with all the info you need

        MediaType mediaType = MediaType.APPLICATION_JSON;
        try{
            mediaType = retrieveRequestMediaType(request);
        } catch(InvalidMediaTypeException imte) {
            // log, do nothing
        }

        // getting the best fitting message converter, according to the "accept" header of the request
        HttpMessageConverter<Object> httpMessageConverter = retrieveMessageConverter(messageConverters, MyErrorResponse.class, mediaType);

        if(httpMessageConverter == null) {
            log.info("Could not find specific handler. Using JSON.");
            httpMessageConverter = retrieveMessageConverter(messageConverters, MyErrorResponse.class, MediaType.APPLICATION_JSON);
        }

        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        ServletServerHttpResponse serverHttpResponse = new ServletServerHttpResponse(errorResponse);
        httpMessageConverter.write(response, mediaType, serverHttpResponse);
    }

}

一旦设置好bean ,是在安全上下文中连接它的时间:

Once you got your bean set up, time to wire it up in the security context:

<beans:bean class="[fully qualified name of the entry point class]" id="myBasicAuthenticationEntryPoint">
    <beans:property name="messageConverters">
        <beans:list>
            <!-- add message converters here -->
            <!-- Spring provide lots of them, google it -->
        </beans:list>
    </beans:property>
</beans:bean>
<http use-expressions="true">
    <http-basic entry-point-ref="myBasicAuthenticationEntryPoint" />
    <!-- add other stuff here, if needed -->
</http>

希望有帮助

这篇关于如何为未经授权的AJAX调用返回JSON响应,而不是作为AJAX响应返回登录页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆