我正在尝试使用自定义身份验证提供程序配置 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/