Spring Security 3.0:基本身份验证提示消失

Spring Security 3.0:基本身份验证提示消失,spring,spring-security,basic-authentication,Spring,Spring Security,Basic Authentication,我正在使用spring basic身份验证,并在我的安全xml中进行以下设置: <http use-expressions="true" create-session="never" > <intercept-url pattern="/**" method="GET" access="isAuthenticated()" /> <intercept-url pattern="/**" method="POST" access="is

我正在使用spring basic身份验证,并在我的安全xml中进行以下设置:

<http use-expressions="true" create-session="never" >
        <intercept-url pattern="/**" method="GET" access="isAuthenticated()" />
        <intercept-url pattern="/**" method="POST" access="isAuthenticated()" />
        <intercept-url pattern="/**" method="PUT" access="isAuthenticated()" />
        <intercept-url pattern="/**" method="DELETE" access="isAuthenticated()" />
        <http-basic />
    </http>

如果身份验证失败,浏览器会弹出一个提示窗口,提示您输入用户名和密码。
有没有办法使该提示根本不弹出?

最有可能的是,用于身份验证失败的页面也受到了保护。您可以尝试手动将失败页面设置为不受保护的页面,如

 <access-denied-handler error-page="/login.jsp"/> 

对于浏览器中的REST API抛出登录对话框,我也遇到了同样的问题。正如您所说,当浏览器将响应头视为

WWW-Authenticate:Basic realm=“Spring安全应用程序

它将提示一个基本身份验证对话框。对于基于REST API的登录,这并不理想。我是这样做的。定义一个自定义身份验证入口点并在开始 将标题设置为“基于表单”

setHeader(“WWW-Authenticate”、“FormBased”)

下面是application-context.xml配置

<security:http create-session="never" entry-point-ref="authenticationEntryPoint" authentication-manager-ref="authenticationManager">
    <security:custom-filter ref="customRestFilter" position="BASIC_AUTH_FILTER" />
    <security:intercept-url pattern="/api/**" access="ROLE_USER" />
</security:http>

<bean id="authenticationEntryPoint" class="com.tito.demo.workflow.security.RestAuthenticationEntryPoint">
</bean>

下面是自定义入口点类

@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private static Logger logger = Logger.getLogger(RestAuthenticationEntryPoint.class);

    public void commence( HttpServletRequest request, HttpServletResponse response,
                          AuthenticationException authException ) throws IOException {
        logger.debug("<--- Inside authentication entry point --->");
        // this is very important for a REST based API login. 
        // WWW-Authenticate header should be set as FormBased , else browser will show login dialog with realm
        response.setHeader("WWW-Authenticate", "FormBased");
        response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
    }


}
@组件
公共类重新验证EntryPoint实现AuthenticationEntryPoint{
私有静态记录器=Logger.getLogger(RestAuthenticationEntryPoint.class);
公共无效开始(HttpServletRequest请求,HttpServletResponse响应,
AuthenticationException(authException)引发IOException{
logger.debug(“”);
//这对于基于REST的API登录非常重要。
//WWW认证头应设置为基于表单,否则浏览器将显示带有域的登录对话框
setHeader(“WWW-Authenticate”、“FormBased”);
response.setStatus(HttpServletResponse.SC_);
}
}
注:我使用了弹簧3.2.5.1释放


现在,当rest API从rest客户端(如POSTMAN)命中时,服务器将返回401 Unauthorized。

我也遇到了同样的问题,我所做的是在我的资源服务器中创建一个自定义的
请求匹配器
。这将阻止Outh2发送
WWW Authenticate header

例如:

 @Override

    public void configure(HttpSecurity http) throws Exception {
         http.requestMatcher(new OAuthRequestedMatcher())
                .authorizeRequests()
                 .antMatchers(HttpMethod.OPTIONS).permitAll()
                    .anyRequest().authenticated();
    }

    private static class OAuthRequestedMatcher implements RequestMatcher {
        public boolean matches(HttpServletRequest request) {
            String auth = request.getHeader("Authorization");
            boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer");
            boolean haveAccessToken = request.getParameter("access_token")!=null;
   return haveOauth2Token || haveAccessToken;
        }
    }

谢谢@enterlezi。我已经尝试添加filters='none',并尝试将自动配置也添加到http元素中,但它不起作用。据我所知,提示是由于WWW-Authenticate:Basic realm=“Spring-Security”应用程序而出现的“在响应的标题中。有没有办法修改响应的标题?我对标题没有任何线索,但我认为问题在于身份验证失败url仍然受到保护。尝试在http定义中添加表单登录元素,例如
,并替换为页面(login.jsp)。另外,请确保使用access=“hasRole('ROLE\u ANONYMOUS')将该页面从筛选器中排除,因为您已指定use expressions=“true”“问题是我没有开发客户端页面。我正在创建使用基本身份验证的RESTAPI。所以我真的没有任何失败的URL重定向到。您知道有没有一种方法可以捕获处理程序中的故障,并在那里控制响应的头文件?好了,这很有意义。如果有帮助,请检查这个答案。非常感谢。我已经像链接中的那个人一样调整了它,它成功了。非常感谢你的帮助!非常感谢。
@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private static Logger logger = Logger.getLogger(RestAuthenticationEntryPoint.class);

    public void commence( HttpServletRequest request, HttpServletResponse response,
                          AuthenticationException authException ) throws IOException {
        logger.debug("<--- Inside authentication entry point --->");
        // this is very important for a REST based API login. 
        // WWW-Authenticate header should be set as FormBased , else browser will show login dialog with realm
        response.setHeader("WWW-Authenticate", "FormBased");
        response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
    }


}
 @Override

    public void configure(HttpSecurity http) throws Exception {
         http.requestMatcher(new OAuthRequestedMatcher())
                .authorizeRequests()
                 .antMatchers(HttpMethod.OPTIONS).permitAll()
                    .anyRequest().authenticated();
    }

    private static class OAuthRequestedMatcher implements RequestMatcher {
        public boolean matches(HttpServletRequest request) {
            String auth = request.getHeader("Authorization");
            boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer");
            boolean haveAccessToken = request.getParameter("access_token")!=null;
   return haveOauth2Token || haveAccessToken;
        }
    }