java - 从 Spring Security 上下文访问应用程序上下文

标签 java spring spring-mvc spring-security

我有一个 Spring MVC 应用程序,它使用 spring security 进行授权。

我实现了一个自定义的 AuthenticationProvider 来授权用户。

我希望这个自定义 AuthenticationProvider 访问应用程序上下文中定义的 bean。

这可能吗?如果是这样,怎么办?

web.xml:

 ...
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>WEB-INF/spring-security.xml</param-value>
 </context-param>
  ...
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
  ...
 <servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>

spring-security.xml:

  ...
  <authentication-manager>
    <authentication-provider ref="customAuthenticationProvider"/>
  </authentication-manager>

  <beans:bean class="com.example.davvstest.CustomAuthenticationProvider" id="customAuthenticationProvider">
    <beans:property name="loginService" ref="loginService" />
  </beans:bean>
  ...

调度程序-servlet.xml:

  <bean class="com.example.davvstest.LoginService" name="loginService">
  </bean>

CustomAuthenticationProvider.java:

package com.example.davvstest;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

public class CustomAuthenticationProvider implements AuthenticationProvider {

    private LoginService loginService;

    public LoginService getLoginService() {
        return loginService;
    }

    public void setLoginService(LoginService loginService) {
        this.loginService = loginService;
    }

    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        if (!loginService.checkAuth(authentication.getName())){
            throw new BadUserNameException("Bad username");
        }
        return authentication;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }

}

LoginService.java:

package com.example.davvstest;

public class LoginService {

    public LoginService() {
    }

    public boolean checkAuth(String username){
        return true;
    }
}

我得到的错误是:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot resolve reference to bean 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0' while setting constructor argument with key [1]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0': Cannot resolve reference to bean 'org.springframework.security.authentication.ProviderManager#0' while setting bean property 'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authentication.ProviderManager#0': Cannot resolve reference to bean 'org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authenticationManager': Cannot resolve reference to bean 'customAuthenticationProvider' while setting constructor argument with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customAuthenticationProvider' defined in ServletContext resource [/WEB-INF/spring-security.xml]: Cannot resolve reference to bean 'loginService' while setting bean property 'loginService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'loginService' is defined

最佳答案

父上下文不能依赖于子上下文。

在本例中,customAuthenticationProvider bean 是父上下文的一部分,它依赖于子 Web 上下文 loginService。

所以你应该

  1. 创建单独的 services-context.xml 并将 loginService bean 定义从dispatcher-servlet.xml 移至 services-context.xml。
  2. 在 web.xml 的 contextConfigLocation 值列表中添加 services-context.xml

关于java - 从 Spring Security 上下文访问应用程序上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18714133/

相关文章:

java - 要在 GWT 中使用 Gears WorkerPool,我是否必须用 Java 和 Javascript 编写相同的代码?

java - Java 中的匿名对象和垃圾收集

java - STRIKE_THRU_TEXT_FLAG 未按预期工作

java - Spring ScriptUtils - PostgreSQL 中未终止的美元报价

java - Spring Hibernate 中的@Transient 方法调用

java - 有没有办法从 Maven 配置中执行批处理文件?

Java Hibernate/Spring,做部分匹配查询 ("contains")?

java - 将 Spring Batch 与 Spring MVC 集成

spring-mvc - 带有休眠验证器的 Spring MVC。如何按组验证属性?

java - 如何调用带有多个参数的spring API?