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

Spring Boot安全性-多WebSecurityConfigurerAdapter

司空和悌
2023-03-14

我有一个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中给出在使用两个身份验证提供程序中的一个登录之间的选项?

编辑

这是我当前对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)

我可以将错误跟踪到https://github.com/spring-projects/spring-security/blob/master/config/src/main/java/org/springframework/security/config/annotation/abstractSecurityBuilder.java中的第44行,但我找不到导致此错误的原因

共有1个答案

景仲渊
2023-03-14

您需要将auth筛选器和username password筛选器放到您自己的配置(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,有两种身份验证方法,auth2和username Password。authenticationBrokerProcessingFilter将处理来自choose.html的请求;

用户名密码筛选器将处理来自登录页面的请求/loginsubmit

auth2过滤器将处理来自sso的/oauth2-login请求

 类似资料:
  • 1.远程执行命令 1.1 危险命令检测. gossh将危险的命令放到黑名单中,一旦远程执行危险命令,会自动退出,通过指定-f参数强制执行。危险命令目前收录如下: "mount", "umount", "rm", "mkfs", "mkfs.ext3", "make.ext2", "make.ext4", "make2fs", "shutdown", "reboot", "init", "dd"

  • 当我使用security.basic.enabled=false在具有以下依赖项的Spring Boot项目上禁用安全性时: 为了修复此异常,我必须添加属性-management.security.enabled=false。我的理解是,当执行器在类路径中时,应该将security.basic.enabled=false和management.security.enabled=false设置为禁用

  • 客户端和服务器间的通信加密 Seafile 在服务器配置了 HTTPS 后,客户端会自动使用 HTTPS 协议和服务器通信。 加密资料库如何工作? 当你创建一个加密资料库,你将为其提供一个密码。所有资料库中的数据在上传到服务器之前都将用密码进行加密。 加密流程: 生成一个32字节长的加密的强随机数。它将被用作文件加密秘钥(“文件秘钥”)。 用用户提供的密码对文件秘钥进行加密 (使用PBKDF2算法

  • 我没有使用Spring Security性,但它要求我进行身份验证。 URL例外(http://localhost:8080/SpringJob/ExecuteJob): application-dev.xml build.gradle片段 控制器

  • 我对maven还很陌生,如果这是一个愚蠢的问题,请向您道歉,但是在我的文件中没有一个文件看起来像文件或类似文件。 (我在#Maven IRC上问过这个问题,但没有人回应。)