I have the following snippet
<http use-expressions="true" auto-config="false"
entry-point-ref="loginUrlAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager" disable-url-rewriting="false">
<!--<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter"
/> -->
<custom-filter position="FORM_LOGIN_FILTER"
ref="usernamePasswordAuthenticationFilter" />
<custom-filter position="LOGOUT_FILTER" ref="tapLockFilter" />
<intercept-url pattern="/session/**" access="permitAll" />
<intercept-url pattern="/deviceregistration/**" access="permitAll" />
<intercept-url pattern="/session/lock" access="hasRole('ROLE_MEMBER')" />
<intercept-url pattern="/app/resources/admin*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/app/SuperAppdashboard*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/app/*" access="hasRole('ROLE_MEMBER')" />
<!--<session-management invalid-session-url="/tizelytics/session/invalidSession"
session-authentication-error-url="/tizelytics/session/accessDenied" session-authentication-strategy-ref="sas">
</session-management> -->
<session-management invalid-session-url="/session/invalidSession"
session-authentication-error-url="/session/accessDenied"
session-fixation-protection="none">
<concurrency-control max-sessions="1"
expired-url="/session/accessExpired" />
</session-management>
</http>
When i run this on server it throws an exception saying
Unsupported configuration attributes: [permitAll, permitAll, hasRole('ROLE_ADMIN'), hasRole('ROLE_ADMIN'), hasRole('ROLE_MEMBER'), hasRole('ROLE_MEMBER')]
here is my access-decision-manager bean within the same xml
<beans:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg>
<beans:list>
<beans:bean
class="org.springframework.security.access.vote.AuthenticatedVoter" />
<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
If i remove the access-decision-manager-ref no exception is thrown the app launches correctly can anyone please advice?
Since you are defining your own accessDecisionManager, I don't see WebExpressionVoter as one of the beans in its list. WebExpressionVoter resolves strings like permitAll(), hasRole(), hasAuthority(), etc. So, your accessDecisionManager bean should be:
<beans:bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<beans:constructor-arg>
<beans:list>
<beans:bean
class="org.springframework.security.access.vote.AuthenticatedVoter" />
<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
<beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean>
Trying to implement spring security oauth2 in my application.
I am able to get access token and refresh token using :
http://localhost:8080/xApp/oauth/token?username=user1&password=password&grant_type=password&client_id=xApp&client_secret=xApp
{
"access_token": "798c7e71-983b-4137-a0cb-ceae4e9b4190"
"token_type": "bearer"
"refresh_token": "0752b8ff-5086-4457-918d-54376c7a2bec"
"expires_in": 299
"scope": "read trust write"
}
When i'm trying to access the protected resource using the below url
http://localhost:8080/xapp/data/product/api/index/?access_token=798c7e71-983b-4137-a0cb-ceae4e9b4190
I am getting:
{
"error": "invalid_token"
"error_description": "Invalid access token: db48214c-04d7-4d6b-aa34-6d16c9c2a438"
}
applicationContext-security.xml :
<?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:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">
<http pattern="/login*" security="none" />
<http pattern="/*.html" security="none" />
<http pattern="/*.pdf" security="none" />
<http pattern="/*.xls" security="none" />
<http pattern="/cache-viewer.jnlp" security="none" />
<!-- /old documentation URLs -->
<!-- servlets -->
<http pattern="/Index" security="none" />
<http pattern="/ServletRedirector" security="none" />
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/data/**" entry-point-ref="oauthAuthenticationEntryPoint"
create-session="never" xmlns="http://www.springframework.org/schema/security"
use-expressions="true">
<anonymous enabled="false" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
</http>
<http pattern="/oauth/token" create-session="stateless"
use-expressions="true">
<!-- authentication-manager-ref="clientAuthenticationManager" -->
<intercept-url pattern="/oauth/token" access="hasRole('Administrator')" />
<anonymous enabled="false" />
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
</http>
<http use-expressions="true" disable-url-rewriting="true" entry-point-ref="authenticationChooser">
<!-- /servlets -->
<intercept-url pattern="/**" access="isAuthenticated()" />
<intercept-url pattern="/" access="isAuthenticated()" />
<form-login login-page="/login" authentication-failure-url="/login?login_error=1" authentication-success-handler-ref="authSuccessHandler"/>
<logout logout-url="/logout" logout-success-url="/login" />
<remember-me key="XappWebClient" services-ref="rememberMeServices" />
<custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
</http>
<beans:bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<beans:property name="realmName" value="Xapp" />
</beans:bean>
<beans:bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<beans:property name="realmName" value="Xapp" />
<beans:property name="typeName" value="Basic" />
</beans:bean>
<beans:bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<beans:bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<beans:property name="authenticationManager" ref="clientAuthenticationManager" />
</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>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<beans:bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<beans:constructor-arg ref="clientDetails" />
</beans:bean>
<!-- This defined token store, we have used inmemory tokenstore for now
but this can be changed to a user defined one -->
<beans:bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />
<!-- This is where we defined token based configurations, token validity
and other things -->
<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="accessTokenValiditySeconds" value="300000"/>
<beans:property name="clientDetailsService" ref="clientDetails" />
</beans:bean>
<beans:bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
<beans:property name="tokenStore" ref="tokenStore" />
<beans:property name="requestFactory" ref="oAuth2RequestFactory" />
</beans:bean>
<beans:bean id="oAuth2RequestFactory"
class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<beans:constructor-arg ref="clientDetails" />
</beans:bean>
<beans:bean id="approvalStore" class="org.springframework.security.oauth2.provider.approval.TokenApprovalStore">
<beans:property name="tokenStore" ref="tokenStore"/>
</beans:bean>
<!-- OAuth2 Authorization Server -->
<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 authentication-manager-ref="authenticationManager"/>
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="Xapp" token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<!-- client -->
<oauth:client client-id="Xapp"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
secret="Xapp" scope="read,write,trust" authorities="Administrator" access-token-validity="300" refresh-token-validity="600"/>
</oauth:client-details-service>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="jaasAuthenticationProvider"/>
</authentication-manager>
<beans:bean id="rememberMeServices"
class="com.Xapp.Xapp.web.authentication.rememberme.RememberMeServices">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="key" value="XappWebClient" />
</beans:bean>
<beans:bean id="jaasNameCallBackHandler"
class="com.Xapp.Xapp.web.authentication.XappNameCallbackHandler">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="callbackHandler">
<beans:bean class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
</beans:property>
</beans:bean>
<beans:bean id="jaasAuthenticationProvider"
class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
<beans:property name="refreshConfigurationOnStartup" value="false"/>
<beans:property name="loginConfig" value="/WEB-INF/login.conf" />
<beans:property name="loginContextName" value="Xapp" />
<beans:property name="callbackHandlers">
<beans:list>
<beans:ref bean="jaasNameCallBackHandler" />
<beans:bean class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler" />
</beans:list>
</beans:property>
<beans:property name="authorityGranters">
<beans:list>
<beans:bean class="com.Xapp.Xapp.web.authentication.XappAuthorityGranter" />
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="userDetailsService" class="com.Xapp.Xapp.web.authentication.XappUserDetailsService">
</beans:bean>
<beans:bean id="jbossSecurityFilter" class="com.Xapp.Xapp.web.authentication.JBossSecurityFilter">
<beans:property name="clientLoginDomain" value="client-login" />
<beans:property name="callbackHandler">
<beans:bean class="com.Xapp.Xapp.web.authentication.SecurityContextHolderAwareCallbackHandler" />
</beans:property>
</beans:bean>
<beans:bean id="authSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="redirectStrategy" ref="XappRedirectStrategy"></beans:property>
</beans:bean>
<beans:bean id="XappRedirectStrategy"
class="com.Xapp.Xapp.web.authentication.XappRedirectStrategy">
</beans:bean>
<beans:bean id="formAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login" />
</beans:bean>
<beans:bean id="authenticationChooser" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
<beans:constructor-arg>
<beans:map>
<beans:entry key="#{new com.Xapp.Xapp.web.authentication.DataRequestMatcher()}" value-ref="oauthAuthenticationEntryPoint" />
</beans:map>
</beans:constructor-arg>
<beans:property name="defaultEntryPoint" ref="formAuthenticationEntryPoint" />
</beans:bean>
</beans:beans>
Controller class path :
#Controller
#RequestMapping("/data/product")
public final class AppController extends AbstractDataController {
#RequestMapping(value = "/index", method = RequestMethod.GET)
#ResponseBody public List<Data> getProducts() throws ServerException {
final List<DataTO> dataTOs = productLogic.findDataTOsForCurrentUser();
Collections.sort(dataTOs, HasName.COMPARATOR);
return ListConverter.convert(dataTOs, fromDataTO);
}
}
Stack trace on debugging second request accessTokenStore is not stored access token is empty :
2016-02-02 11:11:16,268 DEBUG [org.springframework.security.web.context.HttpSessionSecurityContextRepository] (default task-3) HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-02-02 11:11:16,269 DEBUG [org.springframework.security.web.context.HttpSessionSecurityContextRepository] (default task-3) No SecurityContext was available from the HttpSession: io.undertow.servlet.spec.HttpSessionImpl#4439d585. A new one will be created.
2016-02-02 11:11:16,315 DEBUG [org.springframework.security.web.FilterChainProxy] (default task-3) /data/product/index at position 2 of 10 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-02-02 11:11:16,315 DEBUG [org.springframework.security.web.FilterChainProxy] (default task-3) /data/product/index at position 3 of 10 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
2016-02-02 11:11:16,315 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter] (default task-3) Entering Do filter>>>>>>>>>>>>>>>>>>>>
2016-02-02 11:11:16,316 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter] (default task-3) !!!!!!!!!!request>>>>>>>>> org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper#590ca42d
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter] (default task-3) !!!!!!!!!!authentication>>>>>>>>> org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken#763c08a: Principal: 34a81f49-528d-4087-b192-414b6e2224b6; Credentials: [PROTECTED]; Authenticated: false; Details: remoteAddress=127.0.0.1, sessionId=<SESSION>, tokenType=BearertokenValue=<TOKEN>; Not granted any authorities
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager] (default task-3) >>>Call authenticate>>>> token 34a81f49-528d-4087-b192-414b6e2224b6
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.token.DefaultTokenServices] (default task-3) >>>>>>accessTokenValue>>>>>>>>>>>>>>> 34a81f49-528d-4087-b192-414b6e2224b6
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore] (default task-3) >>>>MAP>>>>>>>{}
2016-02-02 11:11:16,317 DEBUG [org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter] (default task-3) <<<<<<<<<<<Trace Error>>>>>>>>>>>>>>>>>>
2016-02-02 11:11:16,339 ERROR [stderr] (default task-3) error="invalid_token", error_description="Invalid access token: 34a81f49-528d-4087-b192-414b6e2224b6"
2016-02-02 11:11:16,339 ERROR [stderr] (default task-3) at org.springframework.security.oauth2.provider.token.DefaultTokenServices.loadAuthentication(DefaultTokenServices.java:237)
2016-02-02 11:11:16,340 ERROR [stderr] (default task-3) at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager.authenticate(OAuth2AuthenticationManager.java:88)
2016-02-02 11:11:16,340 ERROR [stderr] (default task-3) at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:152)
2016-02-02 11:11:16,340 ERROR [stderr] (default task-3) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
2016-02-02 11:11:16,340 ERROR [stderr] (default task-3) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
2016-02-02 11:11:16,340 ERROR [stderr] (default task-3) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
2016-02-02 11:11:16,340 ERROR [stderr] (default task-3) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
2016-02-02 11:11:16,340 ERROR [stderr] (default task-3) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
2016-02-02 11:11:16,340 ERROR [stderr] (default task-3) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
2016-02-02 11:11:16,340 ERROR [stderr] (default task-3) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
Might be duplicate of Oauth2: Invalid access token but it was not answered. Tried on other links in stack couldn't resolve my problem. Any help or suggestions on configuring OAuth2 Spring security 2.0.8 would be great.
We could config using JDBCtokenstore and jwttokenstore as posted in below answer but still can't use InMemorystore any help on this would be great !!!
From the resource APIs it looks like you are passing access_token in the request parameters. You'll have to pass access_token in the request headers like this :
Authorization: Bearer <access_token>
cURL example :
curl -X GET -H "Authorization: Bearer 89af6541-f87f-4c63-be6d-6012426bb745" -H "Cache-Control: no-cache" "http://localhost:8080/xapp/data/product/api/index"
To resolve invalid access token :
we changed storage type from InMemory to database storage (JdbcTokenStore).
Added rememberMeServices for all http tags where spring security URL should be protected in applicationContext-security.xml.
<remember-me key="xAppWebClient" services-ref="rememberMeServices" />
<custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
applicationContext-security.xml changes :
<?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:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">
<http pattern="/Index" security="none" />
<!--This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/data/**" entry-point-ref="oauthAuthenticationEntryPoint"
create-session="never" xmlns="http://www.springframework.org/schema/security"
use-expressions="true">
<anonymous enabled="false" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<intercept-url pattern="/data/**" access="isAuthenticated()" />
<remember-me key="XappWebClient" services-ref="rememberMeServices" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
</http>
<http pattern="/oauth/token" create-session="stateless"
use-expressions="true" authentication-manager-ref="authenticationManager">
<intercept-url pattern="/oauth/token" access="isAuthenticated()" />
<anonymous enabled="false" />
<custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<remember-me key="XappWebClient" services-ref="rememberMeServices" />
<custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
</http>
<http use-expressions="true" disable-url-rewriting="true" entry-point-ref="authenticationChooser">
<!-- /servlets -->
<intercept-url pattern="/**" access="isAuthenticated()" />
<intercept-url pattern="/" access="isAuthenticated()" />
<form-login login-page="/login" authentication-failure-url="/login?login_error=1" authentication-success-handler-ref="authSuccessHandler"/>
<logout logout-url="/logout" logout-success-url="/login" />
<remember-me key="XappWebClient" services-ref="rememberMeServices" />
<custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
</http>
<beans:bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<beans:property name="realmName" value="Xapp" />
</beans:bean>
<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" />
<beans:bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</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>
<beans:bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<beans:constructor-arg ref="clientDetails" />
</beans:bean>
<!-- This defined token store, we have used JdbcTokenStore insted of inmemory tokenstore-->
<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
<beans:constructor-arg name="dataSource" ref="dataSource" />
</beans:bean>
<beans:bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<beans:property name="jndiName">
<beans:value>jdbc/XappDS</beans:value>
</beans:property>
</beans:bean>
<!-- This is where we defined token based configurations, token validity
and other things -->
<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="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
<beans:property name="tokenStore" ref="tokenStore" />
<beans:property name="requestFactory" ref="oAuth2RequestFactory" />
</beans:bean>
<beans:bean id="oAuth2RequestFactory"
class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<beans:constructor-arg ref="clientDetails" />
</beans:bean>
<beans:bean id="approvalStore" class="org.springframework.security.oauth2.provider.approval.TokenApprovalStore">
<beans:property name="tokenStore" ref="tokenStore"/>
</beans:bean>
<!-- OAuth2 Authorization Server -->
<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 authentication-manager-ref="authenticationManager"/>
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="Xapp"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
secret="Xapp" scope="read,write,trust" authorities="Administrator" access-token-validity="300" refresh-token-validity="600"/>
</oauth:client-details-service>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="jaasAuthenticationProvider" />
<authentication-provider user-service-ref="clientDetailsUserService"/>
</authentication-manager>
<beans:bean id="rememberMeServices"
class="com.Xapp.Xapp.web.authentication.rememberme.RememberMeServices">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="key" value="XappWebClient" />
</beans:bean>
<beans:bean id="jaasNameCallBackHandler"
class="com.Xapp.Xapp.web.authentication.XappNameCallbackHandler">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="callbackHandler">
<beans:bean class="org.springframework.security.authentication.jaas.JaasNameCallbackHandler"/>
</beans:property>
</beans:bean>
<beans:bean id="jaasAuthenticationProvider"
class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
<beans:property name="refreshConfigurationOnStartup" value="false"/>
<beans:property name="loginConfig" value="/WEB-INF/login.conf" />
<beans:property name="loginContextName" value="Xapp" />
<beans:property name="callbackHandlers">
<beans:list>
<beans:ref bean="jaasNameCallBackHandler" />
<beans:bean class="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler" />
</beans:list>
</beans:property>
<beans:property name="authorityGranters">
<beans:list>
<beans:bean class="com.Xapp.Xapp.web.authentication.XappAuthorityGranter" />
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="userDetailsService" class="com.Xapp.Xapp.web.authentication.XappUserDetailsService">
</beans:bean>
<beans:bean id="jbossSecurityFilter" class="com.Xapp.Xapp.web.authentication.JBossSecurityFilter">
<beans:property name="clientLoginDomain" value="client-login" />
<beans:property name="callbackHandler">
<beans:bean class="com.Xapp.Xapp.web.authentication.SecurityContextHolderAwareCallbackHandler" />
</beans:property>
</beans:bean>
<beans:bean id="authSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="redirectStrategy" ref="XappRedirectStrategy"></beans:property>
</beans:bean>
<beans:bean id="XappRedirectStrategy"
class="com.Xapp.Xapp.web.authentication.XappRedirectStrategy">
</beans:bean>
<beans:bean id="formAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login" />
</beans:bean>
<beans:bean id="authenticationChooser" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
<beans:constructor-arg>
<beans:map>
<beans:entry key="#{new com.Xapp.Xapp.web.authentication.DataRequestMatcher()}" value-ref="oauthAuthenticationEntryPoint" />
</beans:map>
</beans:constructor-arg>
<beans:property name="defaultEntryPoint" ref="formAuthenticationEntryPoint" />
</beans:bean>
</beans:beans>
Another way we tried is using JwtTokenStore which is great alternative to inmemory. configured like xml :
<http pattern="/login*" security="none" />
<http pattern="/*.html" security="none" />
<http pattern="/*.pdf" security="none" />
<http pattern="/Index" security="none" />
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/restdata/**" entry-point-ref="oauthAuthenticationEntryPoint"
create-session="stateless" xmlns="http://www.springframework.org/schema/security"
use-expressions="true">
<anonymous enabled="false" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<intercept-url pattern="/restdata/**" access="isAuthenticated()" />
<remember-me key="XappWebClient" services-ref="rememberMeServices" />
<custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
</http>
<http pattern="/oauth/token" create-session="stateless"
use-expressions="true" authentication-manager-ref="authenticationManager">
<intercept-url pattern="/oauth/token" access="isAuthenticated()" />
<anonymous enabled="false" />
<custom-filter ref="clientCredentialsTokenEndpointFilter"
before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<remember-me key="XappWebClient" services-ref="rememberMeServices" />
<custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
</http>
<http use-expressions="true" disable-url-rewriting="true"
entry-point-ref="authenticationChooser">
<intercept-url pattern="/**" access="isAuthenticated()" />
<intercept-url pattern="/" access="isAuthenticated()" />
<form-login login-page="/login" authentication-failure-url="/login?login_error=1"
authentication-success-handler-ref="authSuccessHandler" />
<logout logout-url="/logout" logout-success-url="/login" />
<remember-me key="XappWebClient" services-ref="rememberMeServices" />
<custom-filter ref="jbossSecurityFilter" after="REMEMBER_ME_FILTER" />
<custom-filter ref="myFilter" position="PRE_AUTH_FILTER" /> <!--Custom filter intercepts the login request from web client and authorize the user using oauth token request-->
</http>
<beans:bean id="myFilter"
class="com.Xapp.Xapp.web.authentication.XappPreAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<beans:bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<beans:property name="realmName" value="Xapp" />
</beans:bean>
<beans:bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<!-- <beans:property name="realmName" value="Xapp" /> -->
<beans:property name="typeName" value="Basic" />
</beans:bean>
<beans:bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<beans:bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
</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>
<beans:bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<beans:constructor-arg ref="clientDetails" />
</beans:bean>
<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JwtTokenStore">
<beans:constructor-arg ref="jwtTokenEnhancer" />
</beans:bean>
<beans:bean id="jwtTokenEnhancer" class="org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter">
<beans:property name="signingKey" value="Xapp" />
<beans:property name="accessTokenConverter" ref="tokenConverter" />
</beans:bean>
<!-- define token based configurations, token validity and other things -->
<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:property name="tokenEnhancer" ref="jwtTokenEnhancer" />
</beans:bean>
<beans:bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
<beans:property name="tokenStore" ref="tokenStore" />
<beans:property name="requestFactory" ref="oAuth2RequestFactory" />
</beans:bean>
<beans:bean id="oAuth2RequestFactory"
class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<beans:constructor-arg ref="clientDetails" />
</beans:bean>
<beans:bean id="approvalStore" class="org.springframework.security.oauth2.provider.approval.TokenApprovalStore">
<beans:property name="tokenStore" ref="tokenStore"/>
</beans:bean>
<!-- OAuth2 Authorization Server -->
<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 authentication-manager-ref="authenticationManager"/>
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<!-- client -->
<oauth:client client-id="Xapp"
authorized-grant-types="password,authorization_code,refresh_token"
secret="Xapp" scope="read,write,trust" authorities="Administrator"/>
</oauth:client-details-service>
<global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<expression-handler ref="oauthExpressionHandler" />
</global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
<authentication-manager alias="authenticationManager">
<authentication-provider ref="jaasAuthenticationProvider" />
<authentication-provider user-service-ref="clientDetailsUserService"/>
</authentication-manager>
I have application with standard form authentication (username and password). I try to configure OAuth2 in my application. I have configuration in xml. I have a problem that client id and client secret have to be one of users login and password (for example if I have user abc123 with password qwerty I have to set client id to abc123 and client secret qwerty). Can I separate client id and client secret for username and password?
My configuration:
<?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:sec="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.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
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd" >
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<http pattern="/API/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/API/**" access="ROLE_RESTREAD" method="GET" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<http auto-config="false" use-expressions="true"
disable-url-rewriting="true">
<intercept-url pattern="/isSessionValid" access="permitAll"
requires-channel="any" />
<intercept-url pattern="/**" access="isAuthenticated()"
requires-channel="any" />
<form-login login-page="/login" authentication-failure-url="/loginFailed"
default-target-url="/loginSuccess" always-use-default-target="true" />
<logout logout-success-url="/login" />
<session-management>
<concurrency-control max-sessions="1" />
</session-management>
</http>
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:client-credentials />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter" token-services-ref="tokenServices" />
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore" >
<beans:constructor-arg ref="dataSource" />
</beans:bean>
<beans:bean id="clientDetails" class="org.springframework.security.oauth2.provider.client.JdbcClientDetailsService" >
<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="false" />
<beans:property name="clientDetailsService" ref="clientDetails" />
<beans:property name="accessTokenValiditySeconds" value="400000" />
<beans:property name="refreshTokenValiditySeconds" value="0" />
</beans:bean>
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" >
<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>
<beans:bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<beans:property name="realmName" value="theRealm" />
</beans:bean>
<beans:bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<beans:property name="realmName" value="theRealm/client" />
<beans:property name="typeName" value="Basic" />
</beans:bean>
<beans:bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<beans:property name="authenticationManager" ref="aManager" />
</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" />
<global-method-security pre-post-annotations="enabled" proxy-target-class="true">
<expression-handler ref="oauthExpressionHandler" />
</global-method-security>
<authentication-manager alias="aManager">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<beans:bean id="userRepository" class="pl.execon.grm.repository.UserRepository">
<beans:property name="sessionFactory" ref="sessionFactory" />
</beans:bean>
<beans:bean id="userDetailsService" class="pl.execon.grm.auth.GRMUserDataService">
<beans:property name="userRepository" ref="userRepository" />
</beans:bean>
<authentication-manager alias="authManager">
<authentication-provider user-service-ref='userDetailsService'>
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
I resolve my problem. It was in configuration of authentication managers. In XML I have:
<authentication-manager alias="aManager">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
and
<authentication-manager alias="authManager">
<authentication-provider user-service-ref='userDetailsService'/>
</authentication-manager>
This two authentication managers have filed alias so first of them isn't taken to authentication and only second works (when I set username and password). Change alias to id in first authentication manager resolve my problem. Now if I authenticate on getting token the client id and client secret are used.
Linked problem
I am working on a Spring-MVC project in which we are using Spring-Security for authentication, authorization. After recent upgrade of Spring-security to 4.0.1.RELEASE, there were some issues, but I was able to fix them by changing some stuff in the project. Now, the problem is the JSP tags I am using below is not working :
<sec:authorize access="isAnonymous()">
<div class="registerNow btn btn-info btn-lg btn-regBut">
<spring:message code="index.promo.list.item5"/></div>
</sec:authorize>
But If I replace the above with hasRole('ROLE_USER'), then it works, but if the user is already logged in, it does not make any sense to show the registration button. So why is that even if the IDE is suggesting the isAnonymous() it does not work, and what parameter should I pass to access, so that non-authenticated users only will see that button. Thanks a lot. :-)
security-applicationContext.xml :
<security:http pattern="/resources/**" security="none"/>
<security:http create-session="ifRequired" use-expressions="true" auto-config="false" disable-url-rewriting="true">
<security:form-login login-page="/login" username-parameter="j_username" password-parameter="j_password" login-processing-url="/j_spring_security_check" default-target-url="/dashboard" always-use-default-target="true" authentication-failure-url="/denied" />
<security:remember-me key="_spring_security_remember_me" user-service-ref="userDetailsService" token-validity-seconds="1209600" data-source-ref="dataSource"/>
<security:logout delete-cookies="JSESSIONID" invalidate-session="true" logout-url="/j_spring_security_logout"/>
<!-- <security:intercept-url pattern="/**" requires-channel="https"/> -->
<security:intercept-url pattern="/j_spring_security_check" access="permitAll" />
<security:port-mappings>
<security:port-mapping http="8080" https="8443"/>
</security:port-mappings>
<security:logout logout-url="/logout" logout-success-url="/" success-handler-ref="myLogoutHandler"/>
<security:session-management session-fixation-protection="migrateSession">
<security:concurrency-control session-registry-ref="sessionRegistry" max-sessions="5" expired-url="/login"/>
</security:session-management>
<security:csrf disabled="true"/>
</security:http>
<beans:bean id="rememberMeAuthenticationProvider" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<beans:constructor-arg index="0" value="_spring_security_remember_me"/>
<beans:constructor-arg index="1" ref="userDetailsService"/>
<beans:constructor-arg index="2" ref="jdbcTokenRepository"/>
<property name="alwaysRemember" value="true"/>
</beans:bean>
<beans:bean id="jdbcTokenRepository"
class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">
<beans:property name="createTableOnStartup" value="false"/>
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<!-- Remember me ends here -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="LoginServiceImpl">
<security:password-encoder ref="encoder"/>
</security:authentication-provider>
</security:authentication-manager>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="11" />
</beans:bean>
<beans:bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="LoginServiceImpl"/>
<beans:property name="passwordEncoder" ref="encoder"/>
</beans:bean>
</beans>
I am trying to figure out what's the bean configuration for AuthenticationFailureHandler on a REST Login. The usually examples of the AuthenticationFailureHandler are coupled with Form-Login. What I'm trying to achieve is locked an account based on 3 incorrect login attempts. My current bean configuration
<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_USER" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<beans:bean id="restServicesSuccessHandler" class="com.cointraders.api.handlers.RestAuthenticationSuccessHandler" />
<beans:bean id="restServicesFailureHandler" class="com.cointraders.api.handlers.RestAuthenticationFailureHandler" />
<beans:bean id="customUserDetailService" class="com.cointraders.api.services.UserDetailsServiceImpl" />
<beans:bean id="daoProvider" class="com.cointraders.api.daoauthproviders.CustomDaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="customUserDetailService"/>
<beans:property name="passwordEncoder" ref="passwordEncoder" />
</beans:bean>
<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="randomTokenGrant" />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter" resource-id="api" token-services-ref="tokenServices" />