java - 尝试自动连接到自定义身份验证提供程序时,自动连接服务为空

标签 java spring spring-mvc spring-security autowired

我正在尝试使用自定义身份验证提供程序配置 Spring Security。但是我想在服务中 Autowiring 来处理实际的数据库身份验证。我已经验证它在没有这个 Autowiring bean 的情况下也能工作(只是在提供程序中进行硬编码)。我也将 SpringMVC 与 hibernate 结合使用。我目前正在使用根配置(hibernate 等)和使用 java 注释的 webMVC 以及使用 xml 的 spring 进行混合方法。我知道这是不受欢迎的,但我正处于时间紧张状态,并且不想花时间更改 java 配置。

我的 web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/security-context.xml
        </param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

我的安全上下文:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <security:http 
            realm="Protected API"
            use-expressions="true"
            auto-config="false"
            create-session="stateless"
            entry-point-ref="unauthorizedEntryPoint">
        <security:intercept-url pattern="/User/sign_up/*" access="permitAll" />
        <security:intercept-url pattern="/User/authenticate/**" access="permitAll" />
        <security:intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
        <security:custom-filter ref="authenticationTokenFilter" position="FORM_LOGIN_FILTER" />
    </security:http>

    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="customAuthenticationProvider" />
    </authentication-manager>

    <beans:bean id="customAuthenticationProvider" class="pathTo:CustomAuthenticationProvider" />

    <beans:bean id="unauthorizedEntryPoint" class="pathTo:UnauthorizedEntryPoint" />

     <beans:bean id="mySuccessHandler" class="pathTo:SuccessHandler" />

    <beans:bean
        class="com.cheersuniversity.cheers.security.AuthenticationTokenFilter"
        id="authenticationTokenFilter">
        <beans:property name="authenticationManager" ref="authenticationManager" />
        <beans:property name="postOnly" value="false" />
        <beans:property name="authenticationSuccessHandler" ref="mySuccessHandler" />
    </beans:bean>

    <!-- <context:component-scan base-package="com.cheersuniversity.cheers" />
    <context:annotation-config /> -->


</beans:beans>

CustomAuthenticationProvider:这是 Autowired UserService 在 authProvider.isValidLogin 行返回 null 的位置

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserService authService;

    @Override
    public Authentication authenticate(Authentication auth)
            throws AuthenticationException {
        String username = auth.getName();
        String password = auth.getCredentials().toString();
        List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();
        System.out.println(authService == null);
        if (authService.isValidLogin(username, password)) { 
            AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
            return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(), AUTHORITIES);
        }
        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}

用户服务:

@Service
@Transactional
public class UserService {
//Auth code

}

请告诉我是否应该提供更多代码。我发现有些人有必须扫描包裹的问题。当我将该行添加到 security.xml 中时,它在构建时失败,因为没有找到 filterChain 的 bean。根据我的研究,这似乎是一个专家问题,但它无法像其他人修复它的方式来修复。然后我尝试使用下面的 java 配置来实现 spring security,但它仍然存在空指针异常

java-config(尝试):

@Configuration
@EnableWebSecurity
@ComponentScan(basePackages ="correct base package")
@EnableTransactionManagement
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationProvider authenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        authManagerBuilder.authenticationProvider(authenticationProvider);
    }
}

如果您对为什么 Autowiring 为空有任何见解,请告诉我(它在构建时不会失败,只有在身份验证提供程序中调用它时才会失败)。 如有任何帮助,我们将不胜感激!

更新 看来它正在 Autowiring ,但不是正确的版本(实际的 Autowiring 版本)。为什么会这样呢? (我通过在 xml 文件中设置 UserService 的属性值来解决这个问题,然后检查它不为空。但是,验证行仍然有一个空指针。这对我来说非常奇怪。

最佳答案

这是因为我没有在 security-context.xml 中包含以下内容

<context:component-scan base-package="com.cheersuniversity.cheers" />
<context:annotation-config />

我最终意识到另一个错误(FilterBean 没有 Autowiring )是一个单独的问题。一旦我解决了这个问题:请参阅 this question for the answer to that problem

感谢大家的帮助!

关于java - 尝试自动连接到自定义身份验证提供程序时,自动连接服务为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28850804/

相关文章:

java - 从字符串中提取两行数字

java - Wifi 管理器和 WiFi 信息

javascript - 未捕获的 IndexSizeError : ChartJS

java - 为子接口(interface)的 JpaRepository 创建 bean 作为 empRepository 时遇到问题

java - 如何使用<表单:form> </form:form> TAG using HTML in Spring MVC

java - spring security 忽略authentication-failure-url

java - lineChartView 在 fragment 中findViewById

java - 为什么从 Process 的 InputStream 中读取数据是可用的

java - 使用 Spring Boot 将 zip 文件从应用程序资源文件夹复制到目标

java - Spring MVC 重定向属性消息