How to return JSON response for unauthorized AJAX calls instead of login page as AJAX response?

戏子无情 提交于 2020-01-06 01:30:07

问题


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 ?


回答1:


You have to create json for this i am doing here with .net
var url="url";
$.ajax({
    type: "get",
    dataType: "json",
    data:url,
    async: true,
    url: "testCall",//this can be your api or any server side call
    success: function (data) {      
    },
    failure: function () {
        alert(textStatus);
}
});

//here is server side code for creating json

[WebMethod(EnableSession = true)]
[ScriptMethod(UseHttpGet = true)]
public void testCall(string url)
{
 Context.Response.Write()//here your will just hard code the json data
//it will receive by ajax success method.
}



回答2:


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

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

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);
    }

}

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>

Hope it helps



来源:https://stackoverflow.com/questions/33280815/how-to-return-json-response-for-unauthorized-ajax-calls-instead-of-login-page-as

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!