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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24684806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:06:55  来源:igfitidea点击:

How to define a custom AuthenticationEntryPoint without XML configuration

javaspringspring-securityspring-boot

提问by elysch

I've been struggling for a few days now. I'm kind of new in Spring Boot, and like the idea of not using XML configuration.

我已经挣扎了几天了。我是 Spring Boot 的新手,喜欢不使用 XML 配置的想法。

I created a RESTfull application (with JSON). I'm following this tutorialto configure authentication properly.

我创建了一个 RESTfull 应用程序(使用 JSON)。我正在按照本教程正确配置身份验证。

I think I managed to reproduce almost all of its configurations using Java configuration, except for one thing - AuthenticationEntryPoint

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

The tutorial uses a property in httptag like this and defines a formLoginin the following way:

本教程使用了这样的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>

The AuthenticationEntryPointexplanation in the Spring Security manualsays:

Spring Security 手册中AuthenticationEntryPoint解释说:

AuthenticationEntryPoint can be set using the entry-point-ref attribute on the < http > element.

AuthenticationEntryPoint 可以使用 < http > 元素上的 entry-point-ref 属性进行设置。

Doesn't mention anything about how to do it using Java Configuration.

没有提到有关如何使用 Java 配置进行操作的任何信息。

So how can I "register" my own restAuthenticationEntryPointwithout XML in order to prevent the redirection to a login form when using formLogin?

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

Below I will mention what I have tried.

下面我将提到我尝试过的内容。

Thank you all.

谢谢你们。



In my attempts, found you can define it using basicAuthlike this:

在我的尝试中,发现您可以使用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)

But I'm using a form login like this (without the httpBasicpart):

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

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

The problem is it redirects to a login form when it doesn't receive credentials. Since this is a REST service it shouldn't.

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

The documentationfor FormLoginConfigurer(the class .formLogin()uses) says:

文件FormLoginConfigurer(类.formLogin()用途)说:

Shared Objects Created

The following shared objects are populated

AuthenticationEntryPoint

创建的共享对象

填充了以下共享对象

AuthenticationEntryPoint

But couldn't find a way to override it.
Any ideas?

但找不到覆盖它的方法。
有任何想法吗?

P.S.
Don't think it would be a good idea to override the login form to a custom one that only returns the error.

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

采纳答案by Dave Syer

The quote from the ref docs you provided is pointing you at http.exceptionHandling(). You can set up the shared entry point there.

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

http.exceptionHandling().authenticationEntryPoint(myEntryPoint);