Spring oauth2 中的 error="invalid_grant", error_description="Bad credentials"
Posted
技术标签:
【中文标题】Spring oauth2 中的 error="invalid_grant", error_description="Bad credentials"【英文标题】:error="invalid_grant", error_description="Bad credentials" in Spring oauth2 【发布时间】:2015-09-17 13:37:59 【问题描述】:我正在尝试将 Spring security oauth 集成到 struts 应用程序。我遇到了上述错误,我无法解决。我限制 Spring Security 访问 /oauth/token。
ApplicationCONtext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<beans default-autowire="byName">
<!--
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="m2m"/>
</bean>
-->
<bean id="currencyRateService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/CurrencyRateService/remote" />
</bean>
<bean id="reportService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/ReportService/remote" />
</bean>
<bean id="invoiceService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/InvoiceService/remote" />
</bean>
<bean id="entercarduserService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/EnterCardUserService/remote" />
</bean>
<bean id="userService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/UserService/remote" />
</bean>
<bean id="userLoginStatusService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/UserLoginStatusService/remote" />
</bean>
<!-- <bean id="campaignService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/CampaignService/remote" />
</bean> -->
<bean id="rewardService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/RewardService/remote" />
</bean>
<bean id="partnerService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/PartnerService/remote" />
</bean>
<bean id="socialService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/SocialService/remote" />
</bean>
<bean id="activityService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/ActivityService/remote" />
</bean>
<bean id="constantService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/ConstantService/remote" />
</bean>
<bean id="regionService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/RegionService/remote" />
</bean>
<!-- <bean id="verificationService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"
value="m2m/VerificationService/remote" />
</bean> -->
<bean id="trophyService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/TrophyService/remote" />
</bean>
<bean id="contentService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/ContentService/remote" />
</bean>
<bean id="templateService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/TemplateService/remote" />
</bean>
<bean id="partnerUISettingService"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="m2m/PartnerUISettingService/remote" />
</bean>
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/M2MDS" />
</bean>
<!-- Cache -->
<!-- <bean id="cacheManager" class="net.sf.ehcache.CacheManager" factory-method="getInstance" /> -->
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
</bean>
<bean id="sessionCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager" />
<property name="cacheName" value="m2msession" />
</bean>
<bean id="applicationCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager" />
<property name="cacheName" value="m2mapplication" />
</bean>
<bean id="contextCache"
class="com.sinarotech.m2m.web.cache.EhcacheContextCache">
<property name="sessionCache" ref="sessionCache" />
<property name="applicationCache" ref="applicationCache" />
</bean>
<!-- Utils -->
<bean id="contactImporter"
class="com.sinarotech.m2m.contact.OZContactImporter" />
<bean id="helperUtils"
class="com.sinarotech.m2m.web.util.HelperUtils">
<property name="userService" ref="userService" />
<property name="constantService" ref="constantService" />
<property name="rewardService" ref="rewardService" />
</bean>
<bean id="pecuniosusManager"
class="com.sinarotech.m2m.service.PecuniosusManager"
factory-method="getInstance" />
<bean id="config" class="com.sinarotech.m2m.util.Configuration"
factory-method="getInstance" />
<bean id="tipsFactory"
class="com.sinarotech.m2m.web.util.TipsFactory">
<constructor-arg type="java.lang.String" value="tips.drl" />
<property name="config" ref="config" />
</bean>
<bean id="affiliateHandlerFactory"
class="com.sinarotech.m2m.affiliate.AffiliateHandlerFactory"
factory-method="getInstance" />
<bean id="twitterHandler"
class="com.sinarotech.m2m.twitter.AtomTwitterHandler" />
<bean id="bankManager"
class="com.sinarotech.m2m.service.BankManager"
factory-method="getInstance" />
<bean id="exchangeManager"
class="com.sinarotech.m2m.web.util.ExchangeManager">
<constructor-arg value="exchange.properties" />
<property name="userService" ref="userService" />
<property name="contextCache" ref="contextCache" />
</bean>
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean id="supportProvider"
class="com.sinarotech.m2m.support.HelpspotSupportProvider" />
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
</list>
</property>
</bean>
</beans>
</beans>
带有 oauth 的 Spring Security
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="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: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/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- Stateless RESTful services use BASIC authentication -->
<security:http use-expressions="true" auto-config='true' create-session="stateless" authentication-manager-ref="authenticationManager">
<security:intercept-url pattern="/oauth/token"/>
<security:http-basic/>
<anonymous enabled="false"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</security:http>
<oauth:authorization-server client-details-service-ref="client-details-service" token-services-ref="tokenServices">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password authentication-manager-ref="authenticationOauthManager"/>
</oauth:authorization-server>
<beans:bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
</beans:bean>
<beans:bean id="jdbcDaoImpl" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<beans:property name="enableGroups" value="true" />
<beans:property name="enableAuthorities" value="false" />
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<!-- Oauth Client Verification Configuration -->
<oauth:client-details-service id="client-details-service">
<!-- Web Application clients -->
<oauth:client
client-id="NofaAdmin"
secret="655f523128212d6e70634446224c2a48"
authorized-grant-types="password,refresh_token,authorization_code"
access-token-validity="5184000"
refresh-token-validity="5184000"
/>
</oauth:client-details-service>
<beans:bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<beans:property name="typeName" value="Basic"/>
</beans:bean>
<beans:bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>
<!-- Token Generation -->
<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="client-details-service"/>
</beans:bean>
<security:authentication-manager alias="authenticationOauthManager">
<security:authentication-provider>
<security:user-service>
<security:user name="admin" password="password" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<!-- Storing Generated Tokens In Database
--> <!-- <beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
<beans:constructor-arg ref="dataSource" />
</beans:bean> -->
<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"/>
<oauth:resource-server id="resourceServerFilter" token-services-ref="tokenServices"/>
<!-- Security JDBC Authentication Manager -->
<security:authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<security:authentication-provider>
<security:jdbc-user-service data-source-ref="dataSource"
users-by-username-query=
"select email,password,1 from USER where email=?"
authorities-by-username-query=
"select * from ROLE r INNER JOIN (select * from USER u INNER JOIN ROLE_USER ru on u.ID=ru.USER_ID where u.email=? limit 1) roleobj on roleobj.ROLE_ID=r.ID"/>
</security:authentication-provider>
</security:authentication-manager>
</beans:beans>
<!-- <security:global-method-security jsr250-annotations="enabled" access-decision-manager-ref="accessDecisionManager"/>
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.access.annotation.Jsr250Voter"/>
</beans:list>
</beans:property>
</beans:bean> -->
我得到的例外是:
ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[remember.localhost].[/].[spring]] Servlet.service() for servlet spring threw exception: error="invalid_grant", error_description="Bad credentials"
at org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter.getOAuth2Authentication(ResourceOwnerPasswordTokenGranter.java:74) [:]
at org.springframework.security.oauth2.provider.token.AbstractTokenGranter.getAccessToken(AbstractTokenGranter.java:70) [:]
at org.springframework.security.oauth2.provider.token.AbstractTokenGranter.grant(AbstractTokenGranter.java:65) [:]
at org.springframework.security.oauth2.provider.CompositeTokenGranter.grant(CompositeTokenGranter.java:38) [:]
at org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.getAccessToken(TokenEndpoint.java:115) [:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_45]
at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_45]
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) [:3.2.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) [:3.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) [:3.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) [:3.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) [:3.2.6.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) [:3.2.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) [:3.2.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) [:3.2.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936) [:3.2.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827) [:3.2.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734) [:1.0.0.Final]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812) [:3.2.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [:1.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:324) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [:3.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) [:3.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [:3.2.3.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [:3.2.3.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [:3.2.3.RELEASE]
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [:3.2.3.RELEASE]
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [:3.2.3.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [:3.2.3.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [:3.2.3.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) [:3.2.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [:3.2.6.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [:3.2.3.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [:3.2.3.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343) [:3.2.6.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260) [:3.2.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at com.opensymphony.webwork.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:189) [:2.2.6]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.1.0.Final]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [:6.1.0.Final]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [:6.1.0.Final]
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:181) [:6.1.0.Final]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) [:6.1.0.Final]
at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.event(CatalinaContext.java:285) [:1.1.0.Final]
at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.invoke(CatalinaContext.java:261) [:1.1.0.Final]
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:88) [:6.1.0.Final]
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:100) [:6.1.0.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159) [:6.1.0.Final]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [:6.1.0.Final]
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158) [:6.1.0.Final]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [:6.1.0.Final]
at org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve.invoke(ActiveRequestResponseCacheValve.java:53) [:6.1.0.Final]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362) [:6.1.0.Final]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [:6.1.0.Final]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:654) [:6.1.0.Final]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:951) [:6.1.0.Final]
at java.lang.Thread.run(Thread.java:662) [:1.6.0_45]
【问题讨论】:
【参考方案1】:错误的凭据意味着您提供了错误的密码。我猜你提供的是普通密码而不是加密密码?
【讨论】:
“错误凭据”错误伴随着“invalid_grant”错误。所以不应该这样。 您的评论给了我一个提示,我意识到,在 UserDetailsService 实现中,我返回了 UserDetails 而不编码密码。在我的项目中,我使用了密码编码器。一个提示。以上是关于Spring oauth2 中的 error="invalid_grant", error_description="Bad credentials"的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud:Security OAuth2 自定义异常响应
Spring Cloud:Security OAuth2 自定义异常响应
oauth2(spring security)报错method_not_allowed(Request method 'GET' not supported)解决方法
Spring Security Oauth - OAuth2Exceptions 的自定义格式