Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring安全性失败JDBCClientDetails服务错误_Java_Spring_Spring Security_Spring Security Oauth2 - Fatal编程技术网

Java Spring安全性失败JDBCClientDetails服务错误

Java Spring安全性失败JDBCClientDetails服务错误,java,spring,spring-security,spring-security-oauth2,Java,Spring,Spring Security,Spring Security Oauth2,我当前遇到以下错误: org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0 但是,它会引发InternalAuthenticationServiceException异常。这绕过了ProviderManager的异常处理,它不会调用我的customDaoProvider来验证用户 在ProviderManager中注册了2个DaoAuthentic

我当前遇到以下错误:

 org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
但是,它会引发InternalAuthenticationServiceException异常。这绕过了ProviderManager的异常处理,它不会调用我的customDaoProvider来验证用户

在ProviderManager中注册了2个DaoAuthenticationProvider。我的观察是,在ProviderManager的第一次迭代中,它选择DefaultAuthenticationProvider。我想这就是它的工作原理,它会失败,然后ProviderManager会在第二次迭代中选择我的custom DaoAuthenticationProvider(customDaoProvider)来验证用户凭据。事情发生在第一次迭代中,当它失败时,它抛出ProviderManager将重新抛出的特定错误

这在ProviderManager内部,它将捕获特定错误:

  try {
            result = provider.authenticate(authentication);

            if (result != null) {
                copyDetails(authentication, result);
                break;
            }
        } catch (AccountStatusException e) {
            prepareException(e, authentication);
            // SEC-546: Avoid polling additional providers if auth failure is due to invalid account status
            throw e;
        } catch (InternalAuthenticationServiceException e) {
            prepareException(e, authentication);
            throw e;
        } catch (AuthenticationException e) {
            lastException = e;
        }
请注意
InternalAuthenticationServiceException
的捕获。在这里,它将重新引发异常并停止身份验证过程

我的整个security.xml如下(元素除外):


${api.common.login.oauth.token}
${user.login.username.param}
${user.login.password.param}
${api.common.login.oauth.grant\u type.two\u factor}
${api.common.login.oauth.grant\u type.custom\u password}

您可以对客户端和用户使用相同的
AuthenticationManager
,但这只会让生活变得困难,特别是如果您使用
ProviderManager
(与您一样),因为客户端和用户凭据以相同的形式呈现(
UsernamePasswordAuthenticationToken
)。如果您坚持所提供的默认行为,这将容易得多。默认行为是框架为您创建的客户端的一个单独的
AuthenticationManager
。所有的示例和集成测试都使用这种双重身份验证管理器模式,因此有很多东西可以借鉴。

好的,我以前来过这里,尝试过您所说的内容,但几乎没有成功(出现错误)。我用整个security-context.xml修改了我以前的文章。另外,请注意,两种自定义授权类型都返回一个
UsernamePasswordAuthenticationToken
。谢谢,您只需为每个用例创建单独的
AuthenticationManagers
(您现在似乎有3个客户端和2个自定义授权)。我看不出您在哪里保护/token端点,但这是一个具有客户端详细信息的端点(去掉您的
CustomDaoAuthenticationProvider
,并使用常规的
ClientDetailsAuthenticationManager
)。另外两个就在那里,您正在将相同的
AuthenticationManager
注入这两者。
<http pattern="/oauth/token" create-session="stateless"   authentication-manager-ref="authenticationManager" xmlns="http://www.springframework.org/schema/security">
    <intercept-url pattern="/oauth/token" access="ROLE_FRONTEND"  />
    <anonymous enabled="false" />
    <http-basic entry-point-ref="clientAuthenticationEntryPoint"  />

    <custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />

    <access-denied-handler ref="oauthAccessDeniedHandler" />
</http>


 <authentication-manager alias="authenticationManager"  xmlns="http://www.springframework.org/schema/security">
    <sec:authentication-provider user-service-ref="clientDetailsUserService" />
    <sec:authentication-provider ref="customDaoProvider">
    </sec:authentication-provider>
</authentication-manager>


<beans:bean id="customUserDetailService" class="com.xxxx.api.services.UserDetailsServiceImpl">
    <beans:property name="accountService" ref="userAccountServiceImpl"></beans:property>
</beans:bean>

<!-- DAO Providers -->
<beans:bean id="customDaoProvider" class="com.xxxx.api.daoauthproviders.CustomDaoAuthenticationProvider">
    <beans:property name="userDetailsService" ref="customUserDetailService"/>
    <beans:property name="passwordEncoder" ref="passwordEncoder" />
    <beans:property name="accountService" ref="userAccountServiceImpl"></beans:property>
    <beans:property name="clientService" ref="clientServiceImpl"></beans:property>
</beans:bean>
<!-- End of DAO Providers  -->

<beans:bean id="clientDetails" class="org.springframework.security.oauth2.provider.JdbcClientDetailsService">
    <beans:constructor-arg ref="dataSource" />
</beans:bean>

<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans">
    <beans:constructor-arg>
        <beans:list>
            <beans:bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
            <beans:bean class="org.springframework.security.access.vote.RoleVoter" />
            <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
        </beans:list>
    </beans:constructor-arg>
</beans:bean>   

<oauth:authorization-server  client-details-service-ref="clientDetails" token-services-ref="tokenServices">
    <oauth:refresh-token />
    <oauth:client-credentials/>
    <oauth:custom-grant token-granter-ref="customPasswordGrant"/>
    <oauth:custom-grant token-granter-ref="randomTokenGrant" />
</oauth:authorization-server>

<beans:bean id="restServicesSuccessHandler" class="com.xxxx.api.handlers.RestAuthenticationSuccessHandler" />   



<oauth:resource-server id="resourceServerFilter" resource-id="api" token-services-ref="tokenServices" />

<sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">
    <sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>

<oauth:expression-handler id="oauthExpressionHandler" />

<oauth:web-expression-handler id="oauthWebExpressionHandler" />

<beans:bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <beans:property name="realmName" value="api/" />
</beans:bean>

<!-- Custom Grant Types -->
<beans:bean id="randomTokenGrant" class="com.xxxx.api.grants.RandomTokenGrant">
    <beans:constructor-arg index="0"><beans:value>${api.common.login.oauth.token}</beans:value></beans:constructor-arg>
    <beans:constructor-arg index="1"><beans:value>${user.login.username.param}</beans:value></beans:constructor-arg>
    <beans:constructor-arg index="2"><beans:value>${user.login.password.param}</beans:value></beans:constructor-arg>
    <beans:constructor-arg index="3" ref="authenticationManager"></beans:constructor-arg>
    <beans:constructor-arg index="4" ref="tokenServices"></beans:constructor-arg>
    <beans:constructor-arg index="5" ref="clientDetails"></beans:constructor-arg>
    <beans:constructor-arg index="6"><beans:value>${api.common.login.oauth.grant_type.two_factor}</beans:value></beans:constructor-arg>
    <beans:constructor-arg index="7" ref="userAccountServiceImpl"></beans:constructor-arg>
</beans:bean>

<beans:bean id="customPasswordGrant" class="com.xxxx.api.grants.CustomPasswordGrant">
    <beans:constructor-arg index="0" ref="authenticationManager"></beans:constructor-arg>
    <beans:constructor-arg index="1" ref="tokenServices"></beans:constructor-arg>
    <beans:constructor-arg index="2" ref="clientDetails"></beans:constructor-arg>
    <beans:constructor-arg index="3" ref="userAccountServiceImpl"></beans:constructor-arg>
    <beans:constructor-arg index="4"><beans:value>${api.common.login.oauth.grant_type.custom_password}</beans:value></beans:constructor-arg>
</beans:bean>

<!-- End Of Custom Grant Types -->

<beans:bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>


<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.JdbcTokenStore">
    <beans:constructor-arg ref="dataSource" />
</beans:bean>
<beans:bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    <beans:property name="tokenStore" ref="tokenStore" />
    <beans:property name="supportRefreshToken" value="true" />
    <beans:property name="clientDetailsService" ref="clientDetails" />
</beans:bean>

<beans:bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
    <beans:constructor-arg ref="clientDetails" />
</beans:bean>
<beans:bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

<beans:bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <beans:property name="realmName" value="api" />
</beans:bean>

<beans:bean id="clientServiceImpl" class="com.xxxx.api.services.ClientServiceImpl">
    <beans:property name="clientDetailsService" ref="clientDetails" />
</beans:bean>