当前位置: 首页 > 知识库问答 >
问题:

从Spring Boot中的基本身份验证中删除WWW-身份验证标头

经景辉
2023-03-14

我正在使用SpringBoot设计一个REST API。同时,我正在构建一个使用该API的SPA。

为了安全起见,我选择了易于设置的Basic Auth。我现在面临的是401挑战问题。当我的SPA向API发出请求时,如果验证失败,浏览器会显示我想要删除的经典登录弹出窗口。

我到处读到,当401响应还包含一个值为“Basic”的WWW authenticate标头时,浏览器会显示这个弹出窗口。

所以要删除这个,根据Spring Security,我将提供我自己的AuthenticationEntryPoint。有点像Spring Boot默认完成的。我尝试了这个,但它不起作用,我在运行时得到一个堆栈。有什么想法吗?

这是我的密码

@Order(SecurityProperties.BASIC_AUTH_ORDER)
@Configuration
public class CustomWebSecurityConfigurerAdapter extends  WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

       AuthenticationEntryPoint entryPoint = new CustomAuthenticationEntryPoint();

        http
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .authorizeRequests()
            .regexMatchers("/api/.*").authenticated().and()
            .httpBasic().authenticationEntryPoint(entryPoint).and()
            .exceptionHandling().authenticationEntryPoint(entryPoint).and()
            .csrf().disable();

     }
}

这是我使用mvn spring-boot: run运行时得到的堆栈

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:467)
    at java.lang.Thread.run(Thread.java:745)

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:838)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
    at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:347)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:295)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1112)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1101)
    at org.htulipe.WishlistApplication.main(WishlistApplication.java:44)
... 6 more

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 26 more

Caused by: org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:44)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:105)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$7d149fcb.CGLIB$springSecurityFilterChain$6(<generated>)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$7d149fcb$$FastClassBySpringCGLIB$$208d4287.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:318)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$7d149fcb.springSecurityFilterChain(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 27 more

共有3个答案

红存
2023-03-14

如果有人有类似的问题/挑战,我会发布此消息

允许在AuthenticationServerConfigurerAdapter类中进行表单身份验证,如下所示:

 @Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.checkTokenAccess("isAuthenticated()")
    .allowFormAuthenticationForClients();
}

这将允许您在表单中发送client\u id和client\u secret。此外,请确保提交的表单带有内容类型:application/x-www-form-urlencoded标题。

狄令
2023-03-14

有一个更简单的选择。只需将Http401AuthenticationEntryPoint添加到httpSecurity。

http.exceptionHandling()
    .authenticationEntryPoint(new Http401AuthenticationEntryPoint("FormBased"));
尉迟默
2023-03-14

发现问题后,我在问题中发布的堆栈之前发送了另一个堆栈。堆栈抱怨我的身份验证EntryPoint缺少一个领域名称。对于记录,这里是一个工作示例:

public class CustomAuthenticationEntryPoint extends BasicAuthenticationEntryPoint{

    public CustomAuthenticationEntryPoint() {
        this.setRealmName("Yolo");
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
        throws IOException, ServletException {
        response.setHeader("WWW-Authenticate", "FormBased");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
    }
}
 类似资料:
  • http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd“>

  • 问题内容: 从HttpClient 4.3开始,我一直在使用HttpClientBuilder。我正在连接到具有基本身份验证的REST服务。我将凭据设置如下: 但是,这不起作用(我正在使用的REST服务返回401)。怎么了? 问题答案: 从此处的 抢先身份验证 文档中: http://hc.apache.org/httpcomponents-client- ga/tutorial/html/aut

  • 问题内容: 我想写书,所使用的一个一个的NodeJS REST的API服务器Joyent的,并且一切正常,除了我无法验证普通用户的身份验证。如果我跳到终端并执行,则无法在NodeJS http服务器上获取值username:password。如果我的NodeJS http服务器类似于 ,是否应该在来自回调的 req 对象中某处获取值username:password ?如何获得这些值而不必使用Co

  • 本文向大家介绍asp.net mvc中Forms身份验证身份验证流程,包括了asp.net mvc中Forms身份验证身份验证流程的使用技巧和注意事项,需要的朋友参考一下 验证流程 一、用户登录 1、验证表单:ModelState.IsValid 2、验证用户名和密码:通过查询数据库验证 3、如果用户名和密码正确,则在客户端保存Cookie以保存用户登录状态:SetAuthCookie     1

  • 身份验证 PDF版下载 企业应用中的URL链接可以通过OAuth2.0验证接口来获取员工的身份信息。 通过此接口获取员工身份会有一定的时间开销。对于频繁获取员工身份的场景,建议采用如下方案: 企业应用中的URL链接直接填写企业自己的页面地址; 员工跳转到企业页面时,企业校验是否有代表员工身份的cookie,此cookie由企业生成; 如果没有获取到cookie,重定向到OAuth验证链接,获取员工

  • 目前我正在开发一个Java工具,它应该可以更新Confluence服务器页面。使用Curl一切都像一个符咒,但是当使用Postman或Java代码(HttpClient Java11)时,我得到了一个 HTTP状态401–未经授权 反应。 在下面的语句中使用curl curl--basic-u user:password-X PUT-H“内容类型:application/json”-d“@test