Spring Security (4.0.1) 与 AngularJS 的集成。每次用户输入无效凭据时都会弹出基本身份验证

Posted

技术标签:

【中文标题】Spring Security (4.0.1) 与 AngularJS 的集成。每次用户输入无效凭据时都会弹出基本身份验证【英文标题】:Spring Security (4.0.1) Integration with AngularJS. Getting Basic Authentication Popup every time user enters invalid credentials 【发布时间】:2015-07-30 18:48:53 【问题描述】:

我正在尝试将 Spring Security (4.0.1) 与 AngularJS 集成。我能够使用基于 XML 的配置进行基本身份验证。问题是,每次用户输入无效凭据时,Web 浏览器都会显示弹出窗口。我尝试使用普通的 ServletFilters 以及使用基于 Spring 安全性的自定义过滤器来删除 WWW-Authenticate repsone 标头。还没有成功。有人可以帮我解决这个问题吗?

【问题讨论】:

【参考方案1】:

扩展默认 ExceptionTranslationFilter,它为所有 ajax 请求返回 HTTP 401,而不是基本身份验证质询:

package mypackage;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.ExceptionTranslationFilter;

public class AjaxExceptionTranslationFilter extends ExceptionTranslationFilter 

    @Autowired
    public AjaxExceptionTranslationFilter(AuthenticationEntryPoint authenticationEntryPoint) 
        super(authenticationEntryPoint);
    

    @Override
    protected void sendStartAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, AuthenticationException reason)
            throws ServletException, IOException 
        boolean isAjax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));

        if (isAjax) 
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
         else 
            super.sendStartAuthentication(request, response, chain, reason);
        
    

在默认 FILTER_SECURITY_INTERCEPTOR 之前将 AjaxExceptionTranslationFilter 添加到您的配置中:

<security:http pattern="/**">
    <security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="exceptionTranslationFilter"/>
    <!-- ... -->
</security:http>

<bean id="exceptionTranslationFilter" class="mypackage.AjaxExceptionTranslationFilter">
    <constructor-arg ref="loginUrlAuthenticationEntryPoint"/>
</bean>

您需要在 Angular 应用程序中的 ajax 调用中添加 HTTP 标头 X-Requested-With 的拦截器,以便在后端触发 AjaxExceptionTranslationFilter

您还应该从后端捕获 HTTP 401 响应并进行相应处理。

$httpProvider.interceptors.push(['$q', function($q) 
    return 
        'responseError': function(rejection) 
            if(rejection.status === 401) 
                // .. do something meaningful
            


            return $q.reject(rejection);
        
    ;
]);

$httpProvider.interceptors.push(['$q', function ($q) 
    return 
        'request': function (config) 
            config.headers["X-Requested-With"] = "XMLHttpRequest";
            return config || $q.when(config);
        
    ;
]);

]);

【讨论】:

以上是关于Spring Security (4.0.1) 与 AngularJS 的集成。每次用户输入无效凭据时都会弹出基本身份验证的主要内容,如果未能解决你的问题,请参考以下文章

spring security 3.2.0 csrf 令牌在 freemarker 模板中不起作用

Spring- Security :java.lang.NoClassDefFoundError: org/springframework/security/context/DelegatingApp

在多个服务器上使用 Spring Security 和 Spring Redis Session

Spring 中的 spring-security-oauth2 与 spring-security-oauth2-core

Spring Security:如何将两个应用程序与单独的 Spring Security 配置集成?

Spring Security 介绍与Demo