如何在没有 XML 配置的情况下定义自定义 AuthenticationEntryPoint

Posted

技术标签:

【中文标题】如何在没有 XML 配置的情况下定义自定义 AuthenticationEntryPoint【英文标题】:How to define a custom AuthenticationEntryPoint without XML configuration 【发布时间】:2014-09-01 07:35:18 【问题描述】:

我这几天一直在苦苦挣扎。我是 Spring Boot 的新手,喜欢不使用 XML 配置的想法。

我创建了一个 RESTfull 应用程序(使用 JSON)。我正在关注this tutorial 正确配置身份验证。

我想我设法使用 Java 配置重现了几乎所有的配置,除了一件事 - AuthenticationEntryPoint

本教程使用http标签中的一个属性,并以如下方式定义一个formLogin

<http entry-point-ref="restAuthenticationEntryPoint">

  <intercept-url pattern="/api/admin/**" access="ROLE_ADMIN"/>

  <form-login
     authentication-success-handler-ref="mySuccessHandler"
     authentication-failure-handler-ref="myFailureHandler"
  />

  <logout />

</http>

Spring Security manual 中的 AuthenticationEntryPoint 解释说:

AuthenticationEntryPoint 可以使用 元素上的 entry-point-ref 属性来设置。

没有提及如何使用 Java 配置。

那么我如何在没有 XML 的情况下“注册”我自己的 restAuthenticationEntryPoint 以防止在使用 formLogin 时重定向到登录表单?

下面我会提到我尝试过的。

谢谢大家。


在我的尝试中,发现您可以像这样使用 basicAuth 来定义它:

@Configuration
@Order(1)                                                        
public static class RestWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 


        if (restAuthenticationEntryPoint == null) 
            restAuthenticationEntryPoint = new RestAuthenticationEntryPoint();
        

        http
            .authorizeRequests()
                .antMatchers("/**").hasAnyRole(Sec.ADMIN,Sec.SUPER_USER)
...
        .and()
            .httpBasic()
                .authenticationEntryPoint(restAuthenticationEntryPoint)

但我正在使用这样的表单登录(没有 httpBasic 部分):

        .and()
            .formLogin()
                .successHandler(mySavedRequestAwareAuthenticationSuccessHandler)
                .failureHandler(simpleUrlAuthenticationFailureHandler)

问题是它在没有收到凭据时重定向到登录表单。由于这是一项 REST 服务,因此不应该这样做。

FormLoginConfigurer 的 documentation(.formLogin() 使用的类)说:

已创建共享对象

以下共享对象被填充

AuthenticationEntryPoint

但找不到覆盖它的方法。 有什么想法吗?

附言 不要认为将登录表单覆盖为只返回错误的自定义表单是一个好主意。

【问题讨论】:

为什么你有 REST 资源的表单登录?通常一个表单意味着你有一个 GUI(因此重定向到一个视图页面)。也许你只需要 HTTP Basic ? 感谢您的回答。我需要 formLogin 以便拥有一个 cookie,而不是在每个请求上发送凭据。前端是 javascript(其实是 angularJS),我不喜欢在客户端存储用户名和密码的想法 我明白了。你会得到一个用于任何身份验证的 cookie,所以这不一定是一个很好的理由。此外,浏览器可能会为您处理基本身份验证(我假设)。 据我所见,如果我创建一个登录页面并使用基本身份验证与其余服务“对话”,浏览器不会“处理”它。我不得不到处传递凭据。也许我做错了什么。 检查 HTTP 流量。如果您从登录页面获取 cookie,则浏览器应该在每个后续请求中发送它。 【参考方案1】:

您提供的参考文档中的引用指向您http.exceptionHandling()。您可以在那里设置共享入口点。

http.exceptionHandling().authenticationEntryPoint(myEntryPoint);

【讨论】:

这行得通。太感谢了。顺便一提。我找不到教程在哪里讨论 exceptionHandling,而是 RestAuthenticationEntryPoint 的开始方法中的一个参数。你是怎么注意到的? 我的意思是:您在哪里找到了教程中对异常处理的引用,这些引用引导您找到答案。但实际上这只是一个“哇”的评价。 :) 我没有按照教程进行操作。当您了解 API 时,它与 XML 相同,所以我猜到了,但我敢打赌,您可以在 Security ref docs 中找到它。 似乎 Spring Security Reference 没有提到 exceptionHandling() 方法,让用户自己去解决这个问题。 参考中好像没有直接出现,但是可以在Spring文档中找到几个例子:Example 1Example 2

以上是关于如何在没有 XML 配置的情况下定义自定义 AuthenticationEntryPoint的主要内容,如果未能解决你的问题,请参考以下文章

如何自定义VSTS中的版本名称?

大数据技术|Hadoop 3.0: YARN Resource自定义资源配置说明

如何在logback.xml中自定义动态属性

如何在 log4j2.xml 配置中使用 armeria 的 RequestContext 自定义属性?

玩转Spring Boot 自定义配置导入XML配置与外部化配置

怎样在JavaWeb项目中自定义一个配置文件。