Spring boot安全-多个WebSecurityConfigurerAdapter

2024-03-03

我有一个 auth-cas 库,它为我的 Spring Boot 项目提供身份验证。 在这个 auth-cas 库中有一个类扩展WebSecurityConfigurerAdapter具有以下配置功能

@Override
@ConditionalOnProperty(value = "ugent.cas.serviceUrl", matchIfMissing = true)
@ConditionalOnClass(Cas.class)
protected void configure(HttpSecurity http) throws Exception {
    http.exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint());

    if (basicAuthenticationProviders != null) {
        http.addFilter(basicAuthFilter());
    }

    http.addFilter(casAuthenticationFilter())
            .addFilter(requestSSOLogoutToCASServerLogoutFilter())
            .logout()
            .deleteCookies("JSESSIONID")
            .permitAll()
            .logoutSuccessUrl("/logout.html")
            .and()
            .csrf()
            .disable()
            .headers()
            .frameOptions()
            .disable();

    http.authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/api/**").permitAll()
            .antMatchers("/**").authenticated();
}   

因为这应该是黑匣子,所以我添加了自己的WebSecurityConfigurerAdapter看起来像这样:

@Configuration
//@Order(Integer.MAX_VALUE)
//@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@Order(1)
public class AuthSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity
                .ignoring()
                // All of Spring Security will ignore the requests
                .antMatchers("/choose.html")
                .antMatchers("/account/*");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http/*.addFilter(usernamePasswordAuthenticationFilter())
                .formLogin()
                .permitAll()
                .and()
                .logout()
                .deleteCookies("JSESSIONID")
                .permitAll()
                .logoutSuccessUrl("/logout.html")
                .and()
                .csrf()
                .disable()
                .headers()
                .frameOptions()
                .disable();
            */    

                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .authenticationProvider(AuthenticationProvider())
                .formLogin()
                .permitAll()
                .and()
                .csrf()
                .disable()
                .headers()
                .frameOptions()
                .disable()
                ;

    }

    @Bean
    public AuthenticationProvider AuthenticationProvider() {
        return new LCAAuthenticationProvider();
    }

    @Bean
    public UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter () throws Exception{
        UsernamePasswordAuthenticationFilter  filter = new UsernamePasswordAuthenticationFilter ();
        filter.setAuthenticationManager(authenticationManager());
        return filter;
    }
}

我的自定义 AuthenticationProvider 实现了“AuthenticationProvider”,并在页面中将我重定向到 /login 页面,并且我可以使用用户库中的凭据登录。 唯一的问题是,当我已经登录到另一个 auth cas 网络时,我应该经过身份验证,但它仍然提示我使用自定义身份验证提供程序。

我需要如何配置 HttpSecurity 以便它与我的 2 个身份验证提供程序一起使用。

其他相关问题,我如何从被忽略的页面 /choose.html 中提供使用 2 个身份验证提供程序之一登录的选项?

EDIT

这是我当前的“WebSecurityConfigurererAdapter”配置

@Configuration
//@Order(Integer.MAX_VALUE)
//@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@Order(0)
public class AuthSecurityConfiguration extends WebSecurityConfigurerAdapter {

    /**
     * The authProvider bean used as a cas authentication provider.
     */
    @Autowired
    private LCAAuthenticationProvider authProvider;

    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity
                .ignoring()
                // All of Spring Security will ignore the requests
                .antMatchers("/choose.html")
                .antMatchers("/account/*");
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider);
    }

        /**
     * The authenticationManagerBean bean.
     *
     * @return the authenticationManagerBean
     * @throws Exception
     */
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * The loginUrlAuthenticationEntryPoint bean
     *
     * @return the loginUrlAuthenticationEntryPoint
     */
    @Bean
    public LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint() {
        LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint("/choose.html");
        //ep.setLoginUrl(cas.getLoginUrl());

        return ep;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling().authenticationEntryPoint(loginUrlAuthenticationEntryPoint());

        http.addFilter(usernamePasswordAuthenticationFilter())
                .formLogin()
                .permitAll()
                .and()
                .logout()
                .deleteCookies("JSESSIONID")
                .permitAll()
                .logoutSuccessUrl("/logout.html")
                .and()
                .csrf()
                .disable()
                .headers()
                .frameOptions()
                .disable();
            /*  

                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .authenticationProvider(AuthenticationProvider())
                .formLogin()
                .loginPage("choose.html")
                .permitAll()
                .and()
                .csrf()
                .disable()
                .headers()
                .frameOptions()
                .disable()
                ;
           */  
    }

    @Bean
    public LCAAuthenticationProvider lcaAuthenticationProvider() {
        return new LCAAuthenticationProvider();
    }

    @Bean
    public UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter () throws Exception{
        UsernamePasswordAuthenticationFilter  filter = new UsernamePasswordAuthenticationFilter ();
        filter.setAuthenticationManager(authenticationManager());
        return filter;
    }
}

但我收到以下错误:

Exception in thread "main" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:62)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:54)
        ... 1 more
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:839)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
        at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
        at be.ugent.lca.Application.main(Application.java:16)
        ... 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$$699e3cc3.CGLIB$springSecurityFilterChain$2(<generated>)
        at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$699e3cc3$$FastClassBySpringCGLIB$$e656a0ba.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:355)
        at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$699e3cc3.springSecurityFilterChain(<generated>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)

我可以将错误追溯到第 44 行https://github.com/spring-projects/spring-security/blob/master/config/src/main/java/org/springframework/security/config/annotation/AbstractSecurityBuilder.java https://github.com/spring-projects/spring-security/blob/master/config/src/main/java/org/springframework/security/config/annotation/AbstractSecurityBuilder.java但我找不到是什么原因造成的


您需要将身份验证过滤器和用户名密码过滤器放入您自己的配置(AuthSecurityConfiguration)中,并首先进行配置,然后定义choose.html的入口点,以及处理来自的请求的过滤器choose.html然后根据选择重定向到不同的 url(例如 /login 或 /auth)。所以就像下面这样。(我以前做过类似的事情,所以我只是复制它们,你可以更改为你自己的)

<security:http xmlns="http://www.springframework.org/schema/security" entry-point-ref="clientAuthenticationEntryPoint">
        <intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <intercept-url pattern="/choose.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <intercept-url pattern="/autherror" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <intercept-url pattern="/**/**" access="IS_AUTHENTICATED_FULLY"/>
        <custom-filter ref="logoutFilter" position="LOGOUT_FILTER" />
        <custom-filter ref="authenticationBrokerProcessingFilter" after="LOGOUT_FILTER" />
        <custom-filter ref="oauth2ClientContextFilter" after="EXCEPTION_TRANSLATION_FILTER"/>
        <custom-filter ref="oAuth2AuthenticationProcessingFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
        <form-login
                login-page="/login"
                default-target-url="/main"
                username-parameter="username"
                password-parameter="password"
                login-processing-url="/loginSubmit"
                authentication-failure-handler-ref="passwordFailureHandler"
                authentication-success-handler-ref="passwordAuthenticationSuccessHandler"
                always-use-default-target="false"
                />
        <csrf />
        <access-denied-handler ref="accessDeniedHandler" />
    </security:http>


<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
        <constructor-arg name="loginFormUrl" value="/choose.html"/>
    </bean>

正如你在xml中看到的,有两种身份验证方法,oauth2和用户名密码。 身份验证BrokerProcessingFilter将处理来自choose.html的请求;

用户名密码过滤器将处理请求/loginSubmit from login page;

auth2过滤器将处理请求/oauth2-login从 sso 与代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring boot安全-多个WebSecurityConfigurerAdapter 的相关文章

随机推荐

  • 为什么惰性评估有用?

    我长期以来一直想知道为什么惰性评估有用 我还没有人以一种有意义的方式向我解释 大多数情况下 它最终都会归结为 相信我 注意 我的意思不是记忆 主要是因为它可以更有效 如果不使用值 则不需要计算它们 例如 我可以将三个值传递到一个函数中 但根
  • 如何消除数字范围中的重叠 (AWK)

    我正在尝试删除文件内的重叠部分 有一堆以 A 开头的记录 并且具有 起始值 和 结束值 还有一堆以 B 开头的记录 也有范围 并且显示与以 A 开头的记录可能重叠 这个想法是从 A 中删除重叠范围 以便只存在非重叠范围 B 中的某些记录具有
  • 为什么GCC的ifstream >> double分配这么多内存?

    我需要读取一系列数字以空格分隔的人类可读文件 https earth info nga mil GandG wgs84 gravitymod egm96 ww15mgh grd z并做了一些数学计算 但我在读取文件时遇到了一些真正奇怪的内存
  • WPF 在单独的 UI 线程上加载动画? (C#)

    好的 我有一个加载动画 在填充大型数据表时运行 让用户知道程序尚未冻结 我的动画工作正常 但在数据表更新时它也会冻结 是否有某种方法可以拥有多个 UI 线程 以便在 DataTable 加载信息时动画能够继续运行 编辑 当前代码如下 pri
  • 检查 git 存储库的完整性

    当我的磁盘在访问 git 存储库时报告了一长串 不可恢复的读取错误 后 我担心我对其他存储库进行了一些推送 这些存储库可能会将错误的内容转发给它们 顺便说一句 在使用提交 推 拉访问存储库时 没有任何 git 命令报告任何错误 但访问存储库
  • PyQt QML 错误控制台丢失

    标题几乎说明了一切 假设我有这个简单的应用程序 main py gt gt gt import sys from PyQt5 QtCore import QUrl from PyQt5 QtWidgets import QApplicati
  • BeautifulSoup findall 带有类属性 - unicode 编码错误

    我正在使用 BeautifulSoup 从中提取新闻报道 仅标题 黑客新闻 http news ycombinator com到现在为止就这么多了 import urllib2 from BeautifulSoup import Beaut
  • 在具有大标题的导航控制器中时,UIRefreshControl 不会以横向方式显示

    我有一个普通的UITableViewController嵌入一 个UINavigationController which 喜欢大标题 我向表视图控制器添加了刷新控件 在 iOS 11 中的 iPhone 上 如果我以纵向模式启动应用程序
  • 列出已安装的移动配置文件

    在 OSX 上 有什么方法可以以编程方式获取计算机上安装的所有 iOS 移动配置文件的列表 这是您可以在 XCode 管理器中看到的列表 这可能是同一个列表 但如果你看一下 Library MobileDevice Provisioning
  • 为什么运行我的 Java 应用程序时 proxyHost/proxyPort 不起作用?

    我有一个与一些 REST 服务通信的 java 应用程序 我想使用 Fiddler 查看 HTTP 流量 Fiddler 充当 localhost 8888 上的代理 因此以下 Java VM 选项应该配置 java 以使用此代理 Dhtt
  • Android Studio 0.4.0 中添加新首选项屏幕的选项在哪里?

    Android Studio 0 4 0 Hello 我想在 Android Studio 中添加一个新的首选项屏幕 但是 我找不到执行此操作的菜单选项 在 Eclipse 中 您可以右键单击资源目录 新的 xml 文件 资源类型 偏好 但
  • 不小心安装了 python 3.5 与 python3.5:这不好吗?

    我运行预装了 Python 3 4 x 的 Linux Mint 我正在开始一个新项目 想要利用 3 5 左右的东西 所以我决定安装 3 5 并创建指向它的新虚拟环境 所以 我不小心输入了 sudo apt get install pyth
  • 使用 Paramiko SSH 设置 virtualenv

    我在 Windows 中使用 Python 和 Django 的经验有限 现在我试图了解如何将我的代码部署到 Ubuntu 16 04 LTS VPS 在阅读了有关 SE 的各种教程和大量答案后 我成功地取得了很大的进展 好吧 对我来说 但
  • CUT 是否支持多个空格作为分隔符?

    我有这样的文字 word1 word2 word3 word4 一对单词之间可能有多个空格 我想从每行中获取一些单词列 当我使用cat file cut d f1 2 4似乎有些字段是空间 这不是我所期望的 我知道awk可以实现这一点 问题
  • PhantomJSDriver 接受警报

    如何使用 Java 中的 PhantomJSDriver 接受警报 我正在尝试通过 YouTube 来实现这一点 我无法让它工作 我尝试使用此代码在任何驱动程序上接受 但它不适用于 PhantomJS static void confirm
  • 用不同类型的对象填充列表

    我正在研究一种推荐算法 一切正常 但现在我想将这段代码实现到我的开发团队的分支中 我将从顶部开始 我的算法可以推荐两种类型的对象 餐厅和菜肴 餐厅 public class Restaurant public Guid Id get set
  • SignalR Core - 错误:Websocket 已关闭,状态代码:1006

    我在 Angular 应用程序中使用 SignalR 当我销毁 Angular 中的组件时 我也想停止与集线器的连接 我使用命令 this hubConnection stop 但我在 Chrome 控制台中收到错误 Websocket 已
  • 在 Javascript 中从 BLOB URL 读取数据

    我有一个 BLOB URL 我想将其重新创建为第二个 BLOB URL 以便默认下载它 var blob1 new Blob Hello world type text plain url1 window URL createObjectU
  • DatePickerDialog 已将 androidx.fragment.app.DialogFragment 中的按钮涂黑

    这个简单的类 class DateSelectionDialogFragment DialogFragment override fun onCreateDialog savedInstanceState Bundle Dialog val
  • Spring boot安全-多个WebSecurityConfigurerAdapter

    我有一个 auth cas 库 它为我的 Spring Boot 项目提供身份验证 在这个 auth cas 库中有一个类扩展WebSecurityConfigurerAdapter具有以下配置功能 Override Conditional