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

Spring security自定义身份验证提供程序不工作

方波娃
2023-03-14

我正在将应用程序的安全性迁移到Spring Security4.0。我的要求是身份验证应该是JAAS身份验证,自动化数据将从数据库中提取。所以我已经编写和自定义了身份验证提供程序。但我的问题是Spring没有将身份验证请求委托给我的自定义身份验证提供程序。

代码如下

public class CustomAutenticationProvider extends DaoAuthenticationProvider implements AuthenticationProvider {
private AuthenticationProvider delegate;

public CustomAutenticationProvider(AuthenticationProvider delegate) {
    this.delegate = delegate;
}

@Override
public Authentication authenticate(Authentication authentication) {
    Authentication a = delegate.authenticate(authentication);

    if(a.isAuthenticated()){
        a = super.authenticate(a);
    }else{
        throw new BadCredentialsException(messages.getMessage(
                "AbstractUserDetailsAuthenticationProvider.badCredentials",
                "Bad credentials"));
    }

    return a;
}

private List<GrantedAuthority> loadRolesFromDatabaseHere(String name) {
    GrantedAuthority grantedAuthority =new JaasGrantedAuthority(name, new UserPrincipal(name));
    return Arrays.asList(grantedAuthority);
}

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

/* (non-Javadoc)
 * @see org.springframework.security.authentication.dao.DaoAuthenticationProvider#additionalAuthenticationChecks(org.springframework.security.core.userdetails.UserDetails, org.springframework.security.authentication.UsernamePasswordAuthenticationToken)
 */
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails,
        UsernamePasswordAuthenticationToken authentication)
                throws AuthenticationException {


    if(!authentication.isAuthenticated())
        throw new BadCredentialsException(messages.getMessage(
                "AbstractUserDetailsAuthenticationProvider.badCredentials",
                "Bad credentials"));


}
public class CustomUserDetailsService implements UserDetailsService {

private UserDataSource _dataSource = UserDataSource.newInstance();

/* (non-Javadoc)
 * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
 */
@Override
public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {
    System.out.println("loadUserByUsername with param: "+username+" called");
    int _userID;
    UserData _userData = null;
    try {
        _userID = _dataSource.findUserID( username );
        _userData = _dataSource.findByID( _userID );
    } catch (SystemException | SecurityException e) {
        throw new BackEndSystemException("Could not retrieve userId or UserData for userName :"+username);
    }

    return _userData;
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">


<security:authentication-manager id="customAuthManager">
        <security:authentication-provider ref="customauthProvider" />
    </security:authentication-manager>
    <bean id="customauthProvider" class="com.enterprise.security.CustomAutenticationProvider">
        <constructor-arg name="delegate" ref="jaasAuthProvider" />
        <property name="userDetailsService" ref="userDetailsService" />
    </bean>

    <security:http pattern="*/js/**" security="none" />
    <security:http pattern="*/css/**" security="none" />
    <security:http pattern="*/image*" security="none" />
    <security:http pattern="/en/Login*" security="none" />
    <security:http auto-config="true" use-expressions="true">
        <security:csrf disabled="true" />
        <security:intercept-url pattern="/**" access="permitAll" />
        <security:form-login login-page="/en/Login.jsp" default-target-url="/en/account/AccountWelcome.jsp" />
        <security:logout invalidate-session="true" delete-cookies="JSESSIONID" logout-success-url="/en/account/AccountWelcome.jsp" logout-url="/j_spring_security_logout" />
        <!-- 
            <security:session-management session-fixation-protection="newSession"> 
                <security:concurrency-control max-sessions="1" expired-url="/loginfailed"  error-if-maximum-exceeded="false"/> </security:session-management>
        -->
    </security:http>

    <bean id="userDetailsService" class="com.enterprise.security.service.CustomUserDetailsService"></bean>

    <bean id="jaasAuthProvider"
    class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
        <property name="loginConfig" value="classpath:ldap.jaas.config" />
        <property name="authorityGranters">
            <list>
                <bean class="com.enterprise.security.DummyJAASRoleGrantor" />
            </list>
        </property>
        <property name="loginContextName" value="LDAPLogin" />
        <property name="callbackHandlers">
            <list>
                <bean
                    class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler" />
                <bean
                    class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler" />
            </list>
        </property>
    </bean>
</beans>

web.xml条目

    <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns="http://java.sun.com/xml/ns/javaee"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
             id="WebApp_ID" version="3.0">

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/springApplicationContext.xml
        </param-value>
    </context-param>
      
    <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>

调用堆栈

Daemon Thread [http-bio-8080-exec-9] (Suspended (breakpoint at line 29 in CustomUserDetailsService))    
owns: SocketWrapper<E>  (id=407)    
CustomUserDetailsService.loadUserByUsername(String) line: 29    
DaoAuthenticationProvider.retrieveUser(String, UsernamePasswordAuthenticationToken) line: 114   
DaoAuthenticationProvider(AbstractUserDetailsAuthenticationProvider).authenticate(Authentication) line: 143 
ProviderManager.authenticate(Authentication) line: 167  
ProviderManager.authenticate(Authentication) line: 192  
UsernamePasswordAuthenticationFilter.attemptAuthentication(HttpServletRequest, HttpServletResponse) line: 93    
UsernamePasswordAuthenticationFilter(AbstractAuthenticationProcessingFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 217   
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
LogoutFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 120   
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
HeaderWriterFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 64  
HeaderWriterFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107   
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
WebAsyncManagerIntegrationFilter.doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain) line: 53    
WebAsyncManagerIntegrationFilter(OncePerRequestFilter).doFilter(ServletRequest, ServletResponse, FilterChain) line: 107 
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
SecurityContextPersistenceFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 91    
FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse) line: 330 
FilterChainProxy.doFilterInternal(ServletRequest, ServletResponse, FilterChain) line: 213   
FilterChainProxy.doFilter(ServletRequest, ServletResponse, FilterChain) line: 176   
DelegatingFilterProxy.invokeDelegate(Filter, ServletRequest, ServletResponse, FilterChain) line: 344    
DelegatingFilterProxy.doFilter(ServletRequest, ServletResponse, FilterChain) line: 261  
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 241  
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 208  
StandardWrapperValve.invoke(Request, Response) line: 220    
StandardContextValve.invoke(Request, Response) line: 122    
NonLoginAuthenticator(AuthenticatorBase).invoke(Request, Response) line: 505    
StandardHostValve.invoke(Request, Response) line: 170   
ErrorReportValve.invoke(Request, Response) line: 103    
AccessLogValve.invoke(Request, Response) line: 957  
StandardEngineValve.invoke(Request, Response) line: 116 
CoyoteAdapter.service(Request, Response) line: 423  
Http11Processor(AbstractHttp11Processor<S>).process(SocketWrapper<S>) line: 1079    
Http11Protocol$Http11ConnectionHandler(AbstractProtocol$AbstractConnectionHandler<S,P>).process(SocketWrapper<S>, SocketStatus) line: 620   
JIoEndpoint$SocketProcessor.run() line: 318 
ThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1145  
ThreadPoolExecutor$Worker.run() line: 615   
TaskThread$WrappingRunnable.run() line: 61  
TaskThread(Thread).run() line: 724  

共有1个答案

左丘照
2023-03-14

我错过了身份验证管理器中的别名属性。但是为什么这个别名是必要的呢?

<security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="customauthProvider" />
</security:authentication-manager>
 类似资料:
  • 问题内容: 这是我的情况: 一个Web应用程序对许多应用程序执行某种SSO 登录的用户,而不是单击链接,该应用就会向正确的应用发布包含用户信息(名称,pwd [无用],角色)的帖子 我正在其中一个应用程序上实现SpringSecurity以从其功能中受益(会话中的权限,其类提供的方法等) 因此,我需要开发一个 自定义过滤器 -我猜想-能够从请求中检索用户信息,通过自定义 DetailsUserSe

  • 如何通过使用Spring Security和Java配置来定义自定义身份验证提供程序?我想在我自己的数据库上执行一个登录检查凭据。

  • 我想为Spring Security配置L 我配置spring-security.xml指出m 如何设置为 Spring,使用我的自定义类而不是他的 deafaul LDAP 身份验证提供程序?

  • 我有一个正在运行的Spring Boot应用程序(Spring Boot v2.4.1),我想用Spring Boot Admin监控它。 我已经安装了服务器,可以在/actuator/endpoint不安全的情况下监视应用程序的实例。我有一张照片在上面。 现在我想保护它,但我不知道如何在不干扰我当前安全配置的情况下做到这一点。 我将Spring Security配置为匹配数据库中的用户名和密码以

  • 在我的firebase应用程序中,用户可以使用 Google(Firebase的联邦提供商)或 Slack(作为自定义身份验证提供程序实现) 我想给用户链接两个帐户的机会。所以我要开的案子是: 用户使用Google登录 用户转到“设置”并单击“使用松弛连接” 然后应该链接用户帐户,以便他下次可以使用Slack或Google登录 我现在想知道,我是否可以通过某种方式从我的自定义松弛身份验证获得一个A

  • 我正在尝试在Spring身份验证服务器(Spring Security)中配置多个身份验证提供程序(主要和次要) 根据“身份验证”方法留档: 返回:包含凭据的完全经过身份验证的对象。如果AuthenticationProvider无法支持对传递的身份验证对象的身份验证,则可能返回null。在这种情况下,将尝试下一个支持提供的身份验证类的AuthenticationProvider。 如果身份验证失