弹簧security.xml文件
<?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:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd ">
<!-- Default url to get a token from OAuth -->
<http pattern="/api/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<csrf disabled="true"/>
<intercept-url pattern="/api/oauth/token" access="isFullyAuthenticated()"/>
<anonymous enabled="false"/>
<http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<!-- Protected sources -->
<http pattern="/api/services/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint" access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security" use-expressions="true">
<anonymous enabled="false"/>
<intercept-url pattern="/api/**" access="hasRole('ROLE_APP')"/>
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager"/>
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
<bean class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService"/>
</authentication-manager>
<sec:authentication-manager>
<sec:authentication-provider user-service-ref='userDetailsServiceImpl'/>
</sec:authentication-manager>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="userDetailsServiceImpl"></authentication-provider>
</authentication-manager>
<!-- Token store -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
<constructor-arg ref="dataSource"/>
</bean>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="accessTokenValiditySeconds" value="120"/>
<property name="clientDetailsService" ref="clientDetails"/>
</bean>
<bean id="oAuth2RequestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<constructor-arg ref="clientDetails"/>
</bean>
<bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
<property name="tokenStore" ref="tokenStore"/>
<property name="requestFactory" ref="oAuth2RequestFactory"/>
</bean>
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code/>
<oauth:implicit/>
<oauth:refresh-token/>
<oauth:client-credentials/>
<oauth:password/>
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter" resource-id="test" token-services-ref="tokenServices"/>
<bean id="clientDetails" class="com.xxxxxx.service.ClientService"></bean>
<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>
UserServiceImpl
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private OauthRepository oauthRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = oauthRepository.getByUsername(s);
return user;
}
}
ClientServiceImpl
@Component
public class ClientService implements ClientDetailsService {
@Autowired
private OauthRepository oauthRepository;
@Override
public ClientDetails loadClientByClientId(String s) throws ClientRegistrationException {
BaseClientDetails clientDetails = oauthRepository.getByClientId(s);
return clientDetails;
}
}
我一直在搜索,但我无法弄清楚为什么UserServiceImpl
没有被调用。我进行了debbuged并且始终调用ClientServiceImpl
来获取客户端和用户。
在向/api/oauth/token
发送请求后,使用适当的参数(用户和客户端存储在数据库中),我得到:
{"error":"unauthorized","error_description":"Incorrect result size: expected 1, actual 0"}
我正在使用 - Spring Framework 4.2.5.RELEASE - Spring Mvc 4.2.5.RELEASE, - Spring Security 4.1.0.RC1, - Spring Security Oauth2 2.0.9.RELEASE
答案 0 :(得分:0)
我认为你做的很好但是在
@Service public class UserDetailsServiceImpl implements UserDetailsService
您应该设置用户的密码及其角色。
请在此处查看代码
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException
{
System.out.println("Getting access details from Database !!");
// Ideally it should be fetched from database and populated instance of
// #org.springframework.security.core.userdetails.User should be returned from this method
UserDetails user = new User(username, "password", true, true, true, true, new GrantedAuthority[]{ new GrantedAuthorityImpl("ROLE_USER") });
return user;
}
UserDetailsService接口用于查找任何给定用户的用户名,密码和GrantedAuthorities。该接口只提供了一个实现类需要实现的方法。
答案 1 :(得分:0)
我通过spring-security.xml中的以下更改解决了这个问题:
<!-- Default url to get a token from OAuth -->
<http pattern="/api/oauth/token" create-session="stateless"
authentication-manager-ref="authenticationManager"
:
<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="userDetailsServiceImpl"/>
</authentication-manager>
我想我有两个authenticationMangager实例。不管怎样,谢谢。