Why is my Spring oauth server always returning the same access token? - spring

I'm using Spring 4.3.8.RELEASE and spring-boot 1.5.3.RELEASE. I want to serve oauth access tokens to applications with the proper credentials. I'm using the org.springframework.security.oauth2.provider.token.store.JdbcTokenStore class to do this. However, I'm noticing that each time I connect with a client to my server that I have set up with OAuth, the server repeatedly returns the same access token, even after server restarts. My OAuth server configuration is below
<?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:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- The OAuth2 protected resources are separated out into their own block
so we can deal with authorization and error handling separately. This isn't
mandatory, but it makes it easier to control the behaviour. -->
<http pattern="/oauth/(users|clients)/.*" request-matcher="regex"
create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint"
use-expressions="true" xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/oauth/users/([^/].*?)/tokens/.*"
access="#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')"
method="DELETE" />
<intercept-url pattern="/oauth/users/.*"
access="#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('read')"
method="GET" />
<intercept-url pattern="/oauth/clients/.*"
access="#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.isClient() and #oauth2.hasScope('read')"
method="GET" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<expression-handler ref="oauthWebExpressionHandler" />
</http>
<!-- The OAuth2 protected resources are separated out into their own block
so we can deal with authorization and error handling separately. This isn't
mandatory, but it makes it easier to control the behaviour. -->
<http pattern="/me/**" 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="/me" access="ROLE_USER,SCOPE_READ" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="sparklr2" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="sparklr2/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<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.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider>
<user-service id="userDetailsService">
<user name="marissa" password="koala" authorities="ROLE_USER" />
<user name="paul" password="emu" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
<constructor-arg ref="dataSource" />
<property name="authenticationKeyGenerator">
<bean class="org.springframework.security.oauth2.UniqueAuthenticationKeyGenerator" />
</property>
</bean>
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="tokenEnhancer" ref="tokenEnhancer" />
<property name="supportRefreshToken" value="true" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="tokenEnhancer"
class="org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter" />
<bean id="requestFactory"
class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<constructor-arg name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="approvalStore"
class="org.springframework.security.oauth2.provider.approval.TokenApprovalStore">
<property name="tokenStore" ref="tokenStore" />
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:client-credentials />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter" entry-point-ref="entry"
resource-id="myclientAssignment" token-services-ref="tokenServices" />
<bean id="entry" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/assignment" />
</bean>
<context:property-placeholder location="classpath:application.properties"/>
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="${myclient.client.id}"
authorized-grant-types="client_credentials" authorities="ROLE_CLIENT"
access-token-validity="30"
scope="read,write" secret="${myclient.client.secret}" />
</oauth:client-details-service>
<mvc:default-servlet-handler />
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
<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="/**"
access="IS_AUTHENTICATED_FULLY"/>
<custom-filter ref="resourceServerFilter"
before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
</beans>
Here's the shell script I'm using to connect to my local server to retrieve the token ...
#!/bin/bash
ret=$(curl http://localhost:8080/myproject/oauth/token \
-u "myclientid:mysecret" \
-d "grant_type=client_credentials")
echo $ret > /tmp/out
cat /tmp/out
access_token=$( sed -e 's/^.*"access_token":"\([^"]*\)".*$/\1/' /tmp/out )
echo $access_token
Edit:
Per Hans' request, here is an example access token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiZXhwIjoxNDk2ODQ4NDAzLCJhdXRob3JpdGllcyI6WyJST0xFX0NMSUVOVCJdLCJqdGkiOiI4OGMxZjkzZC0wNmRhLTRmYTAtOTM1OS0yZWMxYzU5MWJlMGIiLCJjbGllbnRfaWQiOiJ6aW5jbGVhcm5pbmcifQ.Pf-rjPDj0ZhrNOYuhA0tK8lPLLCzlkqUuFFjb48xskA
and here is a second access token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiZXhwIjoxNDk2OTUzNTg0LCJhdXRob3JpdGllcyI6WyJST0xFX0NMSUVOVCJdLCJqdGkiOiIxM2I5M2M4Ni05MmIwLTQyY2UtYjFkNS1lZjRiNmZhNzJkMzgiLCJjbGllbnRfaWQiOiJ6aW5jbGVhcm5pbmcifQ.GfSHA_JcQg2WHYCI81lunMFIhxdX6REc4goshB2Lck0

This is sample regular access token which when issued will have 30 seconds expiration for your configuration.
You should see the info message (Failed to find access token for token) at the time a new token is issued.
{
"access_token": "e057a4f3-9872-4b97-803e-938ad6ef32db",
"token_type": "bearer",
"refresh_token": "f9a7ea9a-0fd1-45a9-b8ae-de87eaf61787",
"expires_in": 30,
"scope": "read write"
}
This is expected behavior as spring looks into database to verify if the access token for the authentication is already issued.
Subsequent requests until the expiry of token (30s) will not show the message. This message will show up again after old access token is expired and when new token is issued and it continues.
The below line is where that info message is displayed from
https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.java#L168
Refresh token is set to expire in 30 days by default. The similar log message will appear again when the refresh token expires.
It should work similar for JWT access token too.
This is the sequences of log messages when a new token is issued when you run the application in DEBUG logging level.
2017-06-06 14:06:51.339 DEBUG 28732 --- [nio-9191-exec-1] o.s.s.o.p.token.store.JdbcTokenStore : Failed to find access token for authentication org.springframework.security.oauth2.provider.OAuth2Authentication#8e69d9c0: Principal: org.springframework.security.core.userdetails.User#586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_ADMIN, ROLE_USER
2017-06-06 14:06:51.346 DEBUG 28732 --- [nio-9191-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2017-06-06 14:06:51.346 DEBUG 28732 --- [nio-9191-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [select token_id, token from oauth_access_token where token_id = ?]
2017-06-06 14:06:51.347 INFO 28732 --- [nio-9191-exec-1] o.s.s.o.p.token.store.JdbcTokenStore : Failed to find access token for token e057a4f3-9872-4b97-803e-938ad6ef32db
2017-06-06 14:06:51.442 DEBUG 28732 --- [nio-9191-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2017-06-06 14:06:51.443 DEBUG 28732 --- [nio-9191-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)]
2017-06-06 14:06:51.450 DEBUG 28732 --- [nio-9191-exec-1] o.s.jdbc.core.JdbcTemplate : SQL update affected 1 rows
2017-06-06 14:06:51.452 DEBUG 28732 --- [nio-9191-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2017-06-06 14:06:51.452 DEBUG 28732 --- [nio-9191-exec-1] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [insert into oauth_refresh_token (token_id, token, authentication) values (?, ?, ?)]
2017-06-06 14:06:51.455 DEBUG 28732 --- [nio-9191-exec-1] o.s.jdbc.core.JdbcTemplate : SQL update affected 1 rows

Why i am getting same access token for multiple login request?
Ashwani has given answer like below in this post
Access Tokens have fixed Life-Time.
Until that period has not expires, access token remains the same.
During that period if you request access token you will receive the same string but will have reset expiration. It would only happen if
Location, Password etc are exactly same as previous request.
Otherwise new token generated. Sometimes Salesforce resets the
expiration time for last expired token and return in response.
Short-lived access tokens and long-lived refresh tokens
There is no way to expire those tokens directly, so instead, the tokens are issued with a short expiration time so that the application is forced to continually refresh them, giving the service a chance to revoke an application’s access if needed.
#Dave, As you have told that, there is no expiry field, so it is non-expiring access token.
Non-expiring access tokens
Non-expiring access tokens are the easiest method for developers. If you choose this option, it is important to consider the trade-offs you are making.
It isn’t practical to use self-encoded tokens if you want to be able to revoke them arbitrarily. As such, you’ll need to store these tokens in some sort of database, so they can be deleted or marked as invalid as needed.
Note that even if the service intends on issuing non-expiring access tokens for normal use, you’ll still need to provide a mechanism to expire them under exceptional circumstances, such as if the user explicitly wants to revoke an application’s access, or if a user account is deleted.
Non-expiring access tokens are much easier for developers testing their own applications. You can even pre-generate one or more non-expiring access tokens for developers and show it to them on the application details screen. This way they can immediately start making API requests with the token, and not worry about setting up an OAuth flow in order to start testing your API.
In summary, use non-expiring access tokens when:
you have a mechanism to revoke access tokens arbitrarily
you don’t have a huge risk if tokens are leaked
you want to provide an easy authentication mechanism to your
developers
you want third-party applications to have offline access to users’
data
Resource Link: Acess token lifetime
How to refresh access token? Rules are given here: https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/
How to issue an access token are given here:
+----------+
| Resource |
| Owner |
| |
+----------+
v
| Resource Owner
(A) Password Credentials
|
v
+---------+ +---------------+
| |>--(B)---- Resource Owner ------->| |
| | Password Credentials | Authorization |
| Client | | Server |
| |<--(C)---- Access Token ---------<| |
| | (w/ Optional Refresh Token) | |
+---------+ +---------------+
Figure 5: Resource Owner Password Credentials Flow
The flow illustrated in Figure 5 includes the following steps:
(A) The resource owner provides the client with its username and
password.
(B) The client requests an access token from the authorization
server's token endpoint by including the credentials received
from the resource owner. When making the request, the client
authenticates with the authorization server.
(C) The authorization server authenticates the client and validates
the resource owner credentials, and if valid, issues an access
token.
The authorization server MUST follow the rules:
o require client authentication for confidential clients or for any
client that was issued client credentials (or with other
authentication requirements),
o authenticate the client if client authentication is included, and
o validate the resource owner password credentials using its
existing password validation algorithm.
Resource Link: https://www.rfc-editor.org/rfc/rfc6749#page-47

In your configuration you use a JdbcTokenStore :
So, you have to check the table oauth_client_details : you must have a row with a column access_token_validity where you can change in live the duration in seconds.
Another solution is to delete that row and redeploy your application. Your configuration will create the row again with the value you specified in your configuration and that you were speaking about in the conversation.

I know it is very late to post an answer to this question but here is what I think should be considered.
When configuring an Authorization server, one of the parameters is the accessTokenValiditySeconds.
the point here is that it is your solution:
Here is an example of configuring the Authorization server.
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient(ParamsConfig.TRUSTED_CLIENT_ID)
.secret(passwordEncoder.encode(ParamsConfig.TRUSTED_CLIENT_SECRET))
.accessTokenValiditySeconds(10)
.scopes(ParamsConfig.OAUTH_SECURITY_SCOPE)
.authorizedGrantTypes(ParamsConfig.OAUTH_AUTHORIZATION_GRANT_TYPE)
.authorities(ParamsConfig.OAUTH_SECURITY_AUTHORITIES)
.resourceIds(ParamsConfig.OAUTH_SECURITY_RESOURCE_ID);
}
See the accessTokenValiditySeconds that describes two things:
1 - till what time this access token will be valid.
2 - till what time you will be getting the same Access token if you request for an access token.
Note:
This configuration is in Java not xml.
In your case, it should be access-token-validity.

Related

UAA server - org.springframework.security.authentication.BadCredentialsException: Bad credentials

The client needs to get a token from UAA server, but when the request was sent, I alway got the error as follows:
org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent[source=org.springframework.security.authentication.UsernamePasswordAuthenticationToken#48d8d90a: Principal: admin-portal-ui; Credentials: [PROTECTED]; Authenticated: false; Details: remoteAddress=127.0.0.1, clientId=admin-portal-ui; Not granted any authorities]
The UAA server log are shown below:
[2016-11-21 18:40:57.008] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... DEBUG --- UaaRequestMatcher: [loginAuthorizeRequestMatcherOld] Checking match of request : '/uaa/oauth/token'; '/uaa/oauth/authorize' with parameters={login={} and headers {accept=[application/json]}
[2016-11-21 18:40:57.008] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... DEBUG --- UaaRequestMatcher: [passcodeTokenMatcher] Checking match of request : '/uaa/oauth/token'; '/uaa/oauth/token' with parameters={grant_type=password, passcode=} and headers {accept=[application/json, application/x-www-form-urlencoded]}
[2016-11-21 18:40:57.008] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... DEBUG --- CorsFilter: CORS Processing request: URI: /uaa/oauth/token; Scheme: http; Host: localhost; Port: 8080; Origin: http://localhost:81; Method: POST
[2016-11-21 18:40:57.008] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... DEBUG --- CorsFilter: Request cross origin request has passed validation.
[2016-11-21 18:40:57.012] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... DEBUG --- DisableIdTokenResponseTypeFilter: Processing id_token disable filter
[2016-11-21 18:40:57.012] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... DEBUG --- DisableIdTokenResponseTypeFilter: pre id_token disable:false pathinfo:null request_uri:/uaa/oauth/token response_type:token
[2016-11-21 18:40:57.012] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... DEBUG --- DisableIdTokenResponseTypeFilter: post id_token disable:false pathinfo:null request_uri:/uaa/oauth/token response_type:token
[2016-11-21 18:40:57.012] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... DEBUG --- SecurityFilterChainPostProcessor$HttpsEnforcementFilter: Filter chain 'tokenEndpointSecurity' processing request POST /uaa/oauth/token
[2016-11-21 18:40:57.095] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... INFO --- Audit: PrincipalAuthenticationFailure ('null'): principal=admin-portal-ui, origin=[127.0.0.1], identityZoneId=[uaa]
[2016-11-21 18:40:57.095] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... INFO --- Audit: ClientAuthenticationFailure ('Bad credentials'): principal=admin-portal-ui, origin=[remoteAddress=127.0.0.1, clientId=admin-portal-ui], identityZoneId=[uaa]
[2016-11-21 18:40:57.095] cloudfoundry-identity-server - ???? [http-apr-8080-exec-2] .... DEBUG --- CorsFilter: CORS processing completed for: URI: /uaa/oauth/token; Scheme: http; Host: localhost; Port: 8080; Origin: http://localhost:81; Method: POST Status:401
Below is the login-server-security.xml :
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:util="http://www.springframework.org/schema/util"
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/security http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<oauth:resource-server id="oauthResourceAuthenticationFilter" token-services-ref="tokenServices"
resource-id="oauth" entry-point-ref="oauthAuthenticationEntryPoint" />
<http name="secFilterLoginServerAuthenticate" request-matcher-ref="loginAuthenticateRequestMatcher" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
authentication-manager-ref="loginAuthenticationMgr" xmlns="http://www.springframework.org/schema/security" use-expressions="false">
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<custom-filter ref="oauthResourceAuthenticationFilter" position="PRE_AUTH_FILTER" />
<!-- scope authentication filter configured with a scope authentication manager -->
<custom-filter ref="oauthLoginScopeAuthenticatingFilter" after="PRE_AUTH_FILTER"/>
<anonymous enabled="false" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<csrf disabled="true"/>
</http>
<bean id="loginAuthenticateRequestMatcher" class="org.cloudfoundry.identity.uaa.security.web.UaaRequestMatcher">
<constructor-arg value="/authenticate" />
<property name="accept" value="application/json" />
<property name="headers">
<map>
<entry key="Authorization" value="bearer " />
</map>
</property>
</bean>
<sec:http name="secFilterAuthenticateOpen" pattern="/authenticate/**" security="none" />
<http name="secFilterLoginServerAuthorize" request-matcher-ref="loginAuthorizeRequestMatcher" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
authentication-manager-ref="loginAuthenticationMgr" xmlns="http://www.springframework.org/schema/security" use-expressions="false">
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<custom-filter ref="backwardsCompatibleScopeParameter" position="FIRST"/>
<custom-filter ref="oauthResourceAuthenticationFilter" position="PRE_AUTH_FILTER" />
<!-- scope authentication filter configured with a scope authentication manager -->
<custom-filter ref="oauthLoginScopeAuthenticatingFilter" after="PRE_AUTH_FILTER"/>
<custom-filter ref="loginAuthenticationFilter" position="FORM_LOGIN_FILTER" />
<anonymous enabled="false" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<csrf disabled="true"/>
</http>
<bean id="loginAuthorizeRequestMatcher" class="org.cloudfoundry.identity.uaa.security.web.UaaRequestMatcher">
<constructor-arg value="/oauth/authorize" />
<property name="accept" value="application/json" />
<property name="parameters">
<map>
<entry key="source" value="login" />
</map>
</property>
</bean>
<http name="secFilterLoginServerToken" request-matcher-ref="loginTokenRequestMatcher" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
authentication-manager-ref="loginAuthenticationMgr" xmlns="http://www.springframework.org/schema/security" use-expressions="false">
<!--
This represents a /oauth/token requests that gets passed through
from the login server. It assumes that the User has been authenticated
It requires that:
- userid parameter exists
- client_id and client_secret are present
- Bearer token belongs to login server (oauth.login) validated as resource="oauth"
-->
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<!-- the oauthResourceAuthenticationFilter validates the Bearer token
TODO, if there is no token this filter must throw.
What we need is scope=oauth.login
-->
<custom-filter ref="backwardsCompatibleScopeParameter" position="FIRST"/>
<custom-filter ref="oauthResourceAuthenticationFilter" position="PRE_AUTH_FILTER" />
<!-- scope authentication filter configured with a scope authentication manager -->
<custom-filter ref="oauthLoginScopeAuthenticatingFilter" after="PRE_AUTH_FILTER"/>
<!-- filter to validate the client_id and client_secret -->
<custom-filter ref="loginClientParameterAuthenticationFilter" position="FORM_LOGIN_FILTER" />
<!-- The loginServerTokenEndpointAuthenticationFilter validates the user or creates one-->
<custom-filter ref="loginServerTokenEndpointAuthenticationFilter" position="BASIC_AUTH_FILTER"/>
<anonymous enabled="false" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<csrf disabled="true"/>
</http>
<bean id="oauthLoginScopeAuthenticatingFilter" class="org.cloudfoundry.identity.uaa.authentication.manager.ScopeAuthenticationFilter">
<property name="authenticationManager" ref="oauthLoginAuthManager"/>
</bean>
<bean id="oauthLoginAuthManager" class="org.cloudfoundry.identity.uaa.authentication.manager.ScopeAuthenticationManager">
<property name="requiredScopes">
<list>
<value type="java.lang.String">oauth.login</value>
</list>
</property>
</bean>
<bean id="loginTokenRequestMatcher" class="org.cloudfoundry.identity.uaa.security.web.UaaRequestMatcher">
<constructor-arg value="/oauth/token" />
<property name="accept" value="application/json" />
<property name="headers">
<map>
<entry key="Authorization" value="bearer " />
</map>
</property>
<property name="parameters">
<map>
<entry key="source" value="login" />
<entry key="grant_type" value="password" />
<entry key="add_new" value="" />
</map>
</property>
</bean>
<bean id="loginServerTokenEndpointAuthenticationFilter" class="org.cloudfoundry.identity.uaa.authentication.LoginServerTokenEndpointFilter">
<constructor-arg ref="loginAuthenticationMgr" />
<constructor-arg ref="authorizationRequestManager"/>
<constructor-arg ref="addNewUserParameters"/>
<property name="authenticationDetailsSource" ref="authenticationDetailsSource" />
</bean>
<bean id="loginClientParameterAuthenticationFilter" class="org.cloudfoundry.identity.uaa.authentication.LoginClientParametersAuthenticationFilter">
<property name="clientAuthenticationManager" ref="clientAuthenticationManager"/>
</bean>
<!-- Support for older login servers -->
<http name="secFilterLoginServerAuthorizeOld" request-matcher-ref="loginAuthorizeRequestMatcherOld" create-session="always" entry-point-ref="oauthAuthenticationEntryPoint"
authentication-manager-ref="loginAuthenticationMgr" xmlns="http://www.springframework.org/schema/security" use-expressions="false">
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<custom-filter ref="backwardsCompatibleScopeParameter" position="FIRST"/>
<custom-filter ref="oauthResourceAuthenticationFilter" position="PRE_AUTH_FILTER" />
<custom-filter ref="loginAuthenticationFilter" position="FORM_LOGIN_FILTER" />
<anonymous enabled="false" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<csrf disabled="true"/>
</http>
<bean id="loginAuthorizeRequestMatcherOld" class="org.cloudfoundry.identity.uaa.security.web.UaaRequestMatcher">
<constructor-arg value="/oauth/authorize" />
<property name="accept" value="application/json" />
<property name="parameters">
<map>
<entry key="login" value="{" />
</map>
</property>
</bean>
<!-- End support for older login servers -->
<util:list id="addNewUserParameters" value-type="java.lang.String">
<value>login</value>
<value>username</value>
<value>user_id</value>
<value>origin</value>
<value>given_name</value>
<value>family_name</value>
<value>email</value>
<value>authorities</value>
</util:list>
<bean id="loginAuthenticationFilter" class="org.cloudfoundry.identity.uaa.authentication.AuthzAuthenticationFilter">
<constructor-arg ref="loginAuthenticationMgr" />
<property name="parameterNames" ref="addNewUserParameters"/>
</bean>
<bean id="loginAuthenticationMgr" class="org.cloudfoundry.identity.uaa.authentication.manager.LoginAuthenticationManager">
<property name="userDatabase" ref="userDatabase" />
</bean>
<bean class="org.cloudfoundry.identity.uaa.authentication.RemoteAuthenticationEndpoint">
<constructor-arg ref="zoneAwareAuthzAuthenticationManager" />
<property name="loginAuthenticationManager" ref="loginAuthenticationMgr"/>
</bean>
<bean id="codeStore" class="org.cloudfoundry.identity.uaa.codestore.JdbcExpiringCodeStore">
<constructor-arg ref="dataSource" />
</bean>
<bean id="passwordResetEndpoints" class="org.cloudfoundry.identity.uaa.account.PasswordResetEndpoint">
<constructor-arg ref="resetPasswordService"/>
<property name="messageConverters">
<list>
<bean class="org.cloudfoundry.identity.uaa.web.ExceptionReportHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</list>
</property>
<property name="codeStore" ref="codeStore"/>
</bean>
<bean id="changeEmailEndpoints" class="org.cloudfoundry.identity.uaa.scim.endpoints.ChangeEmailEndpoints">
<constructor-arg ref="scimUserProvisioning"/>
<constructor-arg ref="codeStore"/>
<constructor-arg ref="clientDetailsService"/>
</bean>
<http name="secFilterLoginServerPasswordEndpoints" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint" authentication-manager-ref="emptyAuthenticationManager"
access-decision-manager-ref="accessDecisionManager" pattern="/password_*" xmlns="http://www.springframework.org/schema/security" use-expressions="false">
<intercept-url pattern="/**" access="scope=oauth.login" />
<custom-filter ref="oauthResourceAuthenticationFilter" position="PRE_AUTH_FILTER" />
<anonymous enabled="false" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<csrf disabled="true"/>
</http>
<http name="secFilterLoginServerEmailEndpoints" create-session="stateless" entry-point-ref="oauthAuthenticationEntryPoint" authentication-manager-ref="emptyAuthenticationManager"
access-decision-manager-ref="accessDecisionManager" pattern="/email_*" xmlns="http://www.springframework.org/schema/security" use-expressions="false">
<intercept-url pattern="/**" access="scope=oauth.login" />
<custom-filter ref="oauthResourceAuthenticationFilter" position="PRE_AUTH_FILTER" />
<anonymous enabled="false" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
<csrf disabled="true"/>
</http>
</beans>
And there is a configuration uaa.yml as follows:
login:
#Disable create account and forgot password links on the Login Server
selfServiceLinksEnabled: false
# Configure branding for the UAA
branding:
companyName: Consent2Share
productLogo: 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
#Configure to enable to limit login failure attempts
authentication:
policy:
lockoutAfterFailures: 5
countFailuresWithinSeconds: 3600
lockoutPeriodSeconds: 600
# Patient User will use the e-mail server configured in this section to send e-mails
# Please configure valid e-mail server below to connect to SMTP server
# Configure host, port, username and password per environment
smtp:
host: ${UAA_SMTP_HOST}
port: ${UAA_SMTP_PORT}
user: ${UAA_SMTP_USER}
password: ${UAA_SMTP_PASSWORD}
javaMailProperties:
mail:
smtp:
auth: true
starttls:
enable: true
ssl:
trust: ${UAA_SMTP_HOST}
debug: true
spring_profiles: mysql # default is empty
database:
driverClassName: org.mariadb.jdbc.Driver # only if spring_profiles=mysql
url: jdbc:mysql://${C2S_DB_HOST:localhost}:${C2S_DB_PORT:3306}/uaa # only if spring_profiles=mysql
username: root # only if spring_profiles=mysql
password: ${UAA_DB_PASSWORD:wtzhou} # only if spring_profiles=mysql
oauth:
clients:
admin:
secret: adminsecret
authorized-grant-types: client_credentials
scope: uaa.none
authorities: uaa.admin,clients.read,clients.write,clients.secret,scim.read,scim.write,clients.admin
cf: # this client is needed for cf cli and uaac cli to act on user's behalf
authorized-grant-types: implicit,password,refresh_token
scope: uaa.user,cloud_controller.read,cloud_controller.write,openid,password.write,scim.userids,cloud_controller.admin,scim.read,scim.write
authorities: uaa.none
autoapprove: true
patient-portal-ui:
authorized-grant-types: password
#secret: changeit
secret: loginsecret
scope: openid,phr.hie_read,phr.hie_write,phr.patient_read,pcm.provider_read,pcm.provider_create,pcm.provider_delete,pcm.consent_read,pcm.consent_create,pcm.consent_update,pcm.consent_delete,pcm.consent_sign,pcm.consent_revoke,pcm.clinicalDocument_read,pcm.clinicalDocument_create,pcm.clinicalDocument_delete,pcm.activity_read,ppUI.access,tryPolicy.clinicalDocument_read
authorities: uaa.resource
admin-portal-ui:
authorized-grant-types: password
secret: loginsecret
scope: openid,scim.write,scim.read,scim.create,phr.allPatientProfiles_read,phr.hie_write,phr.allPatients_read,phr.patient_read,registration.write,uaa.admin,patientUser.read,patientUser.write,adminUI.access,pep.patient_read
authorities: uaa.resource
patient-user:
secret: loginsecret
authorized-grant-types: client_credentials
scope: uaa.none
authorities: phr.patient_read,phr.allPatientProfiles_read,scim.write,scim.read,scim.create,uaa.admin
azhec-hie:
secret: loginsecret
authorized-grant-types: client_credentials
scope: uaa.none
authorities: pep.patient_read
sysadmin:
secret: loginsecret
authorized-grant-types: client_credentials
scope: uaa.none
authorities: patientUser.scope_assign,scim.write,scim.read,scim.create,uaa.admin
scim:
groups:
phr.hie_read: Access your health information
phr.hie_write: Add your health information
phr.patient_read: Access the patient details
pcm.provider_read: Access provider from list
pcm.provider_create: Create new provider
pcm.provider_delete: Delete provider from list
pcm.consent_read: Access and display your consent
pcm.consent_create: Add new consent
pcm.consent_update: Update current consent
pcm.consent_delete: Delete a consent
pcm.consent_sign: Sign consent
pcm.consent_revoke: Revoke current consent
pcm.clinicalDocument_read: Access and display clinical document
pcm.clinicalDocument_create: Create new clinical document
pcm.clinicalDocument_delete: Delete current clinical document
pcm.activity_read: Access the patient activity history
ppUI.access: Access patient portal UI
pep.patient_read: Access policy enforcement point
tryPolicy.clinicalDocument_read: View policies applied on clinical document
patientUser.scope_assign: Allows Sysadmin to assign scopes to users
users:
# Configure additional c2s staff admin(users) as:
# - EmailId | password | EmailId | FirstName | LastName | <Comma saperated list of permissions>
# For example: - consent2share#gmail.com|admin|consent2share#gmail.com|admin|admin|openid,scim.write,scim.read,scim.create,phr.allPatientProfiles_read,phr.hie_write,phr.allPatients_read,phr.patient_read,registration.write,uaa.admin,patientUser.read,patientUser.write,adminUI.access
- consent2share#gmail.com|admin|consent2share#gmail.com|admin|admin|openid,scim.write,scim.read,scim.create,phr.allPatientProfiles_read,phr.hie_write,phr.allPatients_read,phr.patient_read,registration.write,uaa.admin,patientUser.read,patientUser.write,adminUI.access
# C2S_APP_HOST and C2S_APP_PORT are related to edge server api
c2s:
uaa:
host: http://${C2S_APP_HOST:localhost}:${C2S_APP_PORT:81}/uaa
jwt:
token:
verification-key: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0m59l2u9iDnMbrXHfqkO
rn2dVQ3vfBJqcDuFUK03d+1PZGbVlNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7
fYb3d8TjhV86Y997Fl4DBrxgM6KTJOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQB
LCl0vpcXBtFLMaSbpv1ozi8h7DJyVZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDO
kqwIn7Glry9n9Suxygbf8g5AzpWcusZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPo
jfj9Cw2QICsc5+Pwf21fP+hzf+1WSRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nI
JwIDAQAB
-----END PUBLIC KEY-----
signing-key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA0m59l2u9iDnMbrXHfqkOrn2dVQ3vfBJqcDuFUK03d+1PZGbV
lNCqnkpIJ8syFppW8ljnWweP7+LiWpRoz0I7fYb3d8TjhV86Y997Fl4DBrxgM6KT
JOuE/uxnoDhZQ14LgOU2ckXjOzOdTsnGMKQBLCl0vpcXBtFLMaSbpv1ozi8h7DJy
VZ6EnFQZUWGdgTMhDrmqevfx95U/16c5WBDOkqwIn7Glry9n9Suxygbf8g5AzpWc
usZgDLIIZ7JTUldBb8qU2a0Dl4mvLZOn4wPojfj9Cw2QICsc5+Pwf21fP+hzf+1W
SRHbnYv8uanRO0gZ8ekGaghM/2H6gqJbo2nIJwIDAQABAoIBAHPV9rSfzllq16op
zoNetIJBC5aCcU4vJQBbA2wBrgMKUyXFpdSheQphgY7GP/BJTYtifRiS9RzsHAYY
pAlTQEQ9Q4RekZAdd5r6rlsFrUzL7Xj/CVjNfQyHPhPocNqwrkxp4KrO5eL06qcw
UzT7UtnoiCdSLI7IL0hIgJZP8J1uPNdXH+kkDEHE9xzU1q0vsi8nBLlim+ioYfEa
Q/Q/ovMNviLKVs+ZUz+wayglDbCzsevuU+dh3Gmfc98DJw6n6iClpd4fDPqvhxUO
BDeQT1mFeHxexDse/kH9nygxT6E4wlU1sw0TQANcT6sHReyHT1TlwnWlCQzoR3l2
RmkzUsECgYEA8W/VIkfyYdUd5ri+yJ3iLdYF2tDvkiuzVmJeA5AK2KO1fNc7cSPK
/sShHruc0WWZKWiR8Tp3d1XwA2rHMFHwC78RsTds+NpROs3Ya5sWd5mvmpEBbL+z
cl3AU9NLHVvsZjogmgI9HIMTTl4ld7GDsFMt0qlCDztqG6W/iguQCx8CgYEA3x/j
UkP45/PaFWd5c1DkWvmfmi9UxrIM7KeyBtDExGIkffwBMWFMCWm9DODw14bpnqAA
jH5AhQCzVYaXIdp12b+1+eOOckYHwzjWOFpJ3nLgNK3wi067jVp0N0UfgV5nfYw/
+YoHfYRCGsM91fowh7wLcyPPwmSAbQAKwbOZKfkCgYEAnccDdZ+m2iA3pitdIiVr
RaDzuoeHx/IfBHjMD2/2ZpS1aZwOEGXfppZA5KCeXokSimj31rjqkWXrr4/8E6u4
PzTiDvm1kPq60r7qi4eSKx6YD15rm/G7ByYVJbKTB+CmoDekToDgBt3xo+kKeyna
cUQqUdyieunM8bxja4ca3ukCgYAfrDAhomJ30qa3eRvFYcs4msysH2HiXq30/g0I
aKQ12FSjyZ0FvHEFuQvMAzZM8erByKarStSvzJyoXFWhyZgHE+6qDUJQOF6ruKq4
DyEDQb1P3Q0TSVbYRunOWrKRM6xvJvSB4LUVfSvBDsv9TumKqwfZDVFVn9yXHHVq
b6sjSQKBgDkcyYkAjpOHoG3XKMw06OE4OKpP9N6qU8uZOuA8ZF9ZyR7vFf4bCsKv
QH+xY/4h8tgL+eASz5QWhj8DItm8wYGI5lKJr8f36jk0JLPUXODyDAeN6ekXY9LI
fudkijw0dnh28LJqbkFF5wLNtATzyCfzjp+czrPMn9uqLNKt/iVD
-----END RSA PRIVATE KEY-----
I have been tried to find the reason for a long time, but I still cannot get it done. Could anyone help me to figure out what is the root cause for the error? Any reply will be very appreciated!
I think you need to add some authorities to the client (admin-portal-ui) you are using. Most likely adding oauth.login should do.
Please refer to sample client xml oauth-clients.xml on github uaa repo.
You may need something similar to the login client. In this xml, you can find many more authorities added to the login client. You can try adding all of them.
Another point you may want to check is the origin of the user, if you are trying to acquire token on behalf of the user without his password. In this case the origin must NOT be uaa

How to make the refresh token life long valid and issue a new refresh token each time a new refresh_token grant_type comes in spring security oauth2

I am using spring security oauth2 for authentication for my android application clients.When the client request comes with grant_type as password the server issues the access token and refresh token.If the access token expires i can issue a new access token by sending a request with grant_type as refresh_token.Now what will i do if my refresh token expires?I dont want to prompt the users to authenticate again using his credentials.So is there a way to issue a new refresh token along with the new access token? or is there any provision to issue a refresh token with infinite validity or by sending a refresh token with single time use only and refresh the refresh token in each refresh_token grant_type request.Below is my configuration file for spring security oauth2.
<?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-1.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.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 ">
<!-- This is default url to get a token from OAuth -->
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/protected/**" 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="/protected/**" access="ROLE_APP" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test" />
</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" />
<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.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="userService">
</authentication-provider>
</authentication-manager>
<bean id="userService"
class="com.example.myproject.ser.UserService">
</bean>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<!-- This defined token store, we have used inmemory tokenstore for now
but this can be changed to a user defined one -->
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<!-- This is where we defined token based configurations, token validity
and other things -->
<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" /> <!-- 2 hour 3600 -->
<property name="refreshTokenValiditySeconds" value="420"></property> <!-- 2 month 5270400 -->
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<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.example.myproject.ser.ClientService">
</bean>
<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<!--you could also wire in the expression handler up at the layer of the
http filters. See https://jira.springsource.org/browse/SEC-1452 -->
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
</beans>
In my android application i have the provision to authenticate the same user from multiple devices.That is one can authenticate in any device if already he is authenticated in other device.So the solution don't affect this case.
You can set validity period for the refresh token either at the client level (see org.springframework.security.oauth2.provider.ClientDetails and org.springframework.security.oauth2.provider.ClientDetailsService).
You'll need to set this on the client as it's loaded by the client details service.
public classs MyClientDetailsService implements ClientDetailsService {
#Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
BaseClientDetails client = new BaseClientDetails();
client.setRefreshTokenValiditySeconds(Integer.MAX_VALUE);
...
return client;
}
}
Alternatively, you can set a default validity on org.springframework.security.oauth2.provider.token.DefaultTokenServices (assuming that is the implementation that you are using in your server) in your authorisation server configuration. You can do this by adding the following method to your authorisation server configuration class.
#Bean
public AuthorizationServerTokenServices authorizationServerTokenServices() throws Exception {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(tokenStore);
tokenServices.setSupportRefreshToken(true);
tokenServices.setClientDetailsService(clientDetailsService);
tokenServices.setRefreshTokenValiditySeconds(Integer.MAX_VALUE);
return tokenServices;
}
Once that refresh token has expired though, I believe the only way to obtain a new one is for the user to re-authenticate.
According to the source code for spring-security-oauth in the DefaultTokenServices passing a value less or equal to zero as the validity of the refresh token should be enough to make it last forever. Check it out here.
Then the code in the authorisation server configuration should be like this:
#Bean
fun tokenServices(): DefaultTokenServices {
val defaultTokenServices = DefaultTokenServices()
defaultTokenServices.setTokenStore(tokenStore())
defaultTokenServices.setRefreshTokenValiditySeconds(0)
return defaultTokenServices
}
Or if you have a JdbcClientDetailsService you can set the refresh token expiry in the oauth_client_detailstable.

Fail to locate j_spring_security_check in Spring Security

I am working on spring Security, I am facing the issue "Problem accessing /CustomRole/j_spring_security_check"
My web.xml file is as follow
<sec:http auto-config="true" disable-url-rewriting="true"
use-expressions="true">
<!-- When access is refused, will go to the 403.jsp -->
<sec:intercept-url pattern="/login.jsp" filters="none" />
<sec:form-login login-page="/login.jsp"
authentication-failure-url="/login.jsp?error=true"
login-processing-url="/j_spring_security_check.action"
default-target-url="/index.jsp"
always-use-default-target="true" />
<sec:logout logout-success-url="/login.jsp" />
<sec:http-basic />
<!-- An increase in filter and Acegi, this is not the same, can not modify
the default filter, the filter is located in the FILTER_SECURITY_INTERCEPTOR
before> -->
<sec:custom-filter before="FILTER_SECURITY_INTERCEPTOR"
ref="myFilter" />
</sec:http>
<!-- A custom filter, you must include the authenticationManager, accessDecisionManager,
securityMetadataSource three attributes, All control we will achieve in the
three class, explain the specific configuration, see> -->
<beans:bean id="myFilter"
class="com.demo.security.MyFilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="accessDecisionManager" ref="myAccessDecisionManagerBean" />
<beans:property name="securityMetadataSource" ref="securityMetadataSource" />
</beans:bean>
<!-- The authentication manager, entrance for user authentication, which
implements the UserDetailsService interface can be -->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailService">
<!-- If the user's password using encryption, you can add a little salt
"" <password-encoder hash="md5"/> -->
</authentication-provider>
</authentication-manager>
<beans:bean id="myUserDetailService" class="com.demo.security.MyUserDetailService" />
<!-- Access decision device, determines whether a user has a role, that
you have sufficient permissions to access a resource -->
<beans:bean id="myAccessDecisionManagerBean" class="com.demo.security.MyAccessDecisionManager">
</beans:bean>
<!-- Resource source data definition, the definition of a resource can be
what role access -->
<beans:bean id="securityMetadataSource"
class="com.demo.security.MyInvocationSecurityMetadataSource" />
After hitting the launch page it open login page successfully.But when i provide login credential and try to hit login it fails and throw error related to "j_spring_security_check"
I have created code as per the available on http://www.programering.com/a/MTNygjMwATY.html

Spring security remember me not working, getting SecurityContex tHolder not populated with remember-me token

i have below code to enable remember me authentication in configuration xml
<remember-me services-ref="rememberMeServices" key="testKeyForBlog" />
<beans:bean id="rememberMeServices" class="com.ringee.web.login.security.controller.CustomTokenBasedRememberMeServices">
<beans:constructor-arg name="key" value="testKeyForBlog"/>
<beans:constructor-arg name="manageUserServiceImpl" ref="manageUserServiceImpl" />
<beans:constructor-arg name="tokenRepository" ref="managePersistentTokenServiceImpl" />
</beans:bean>
i have implemented AbstractRememberMeServices to have custom remember me authentication.
when i enter my login id and password with remember me check box enabled, RememberMeAuthenticationFilter filter is invoked, but below line
SecurityContextHolder.getContext().getAuthentication() == null
where authentication object is not null, which eventually make remember me service not invoked, after running in debug mode , i see below debug message
DEBUG [org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter] (http--127.0.0.1-8080-6) SecurityContex
tHolder not populated with remember-me token, as it already contained: 'com.ringee.web.login.security.controller.CustomUserAuthentication#6ee367b0'
my application doesnt has form login, instead does ajax login, hence i have customized. i have custom entry point.
<http pattern="/**" entry-point-ref="customEntryPoint">
<custom-filter ref="ajaxTimeoutRedirectFilter" after="EXCEPTION_TRANSLATION_FILTER" />
<remember-me services-ref="rememberMeServices" key="testKeyForBlog" />
<custom-filter position="PRE_AUTH_FILTER" ref="ringeeFilter" />
<intercept-url pattern="/index.jsp" access="ROLE_ANONYMOUS" />
<intercept-url pattern="/menu/registration" access="ROLE_ANONYMOUS" />
<custom-filter ref="logOutFilter" position="LOGOUT_FILTER" />
<access-denied-handler ref="accessDeniedHandler" />
</http>
when login with remember me check box enable.. no cookie is been set because remember service is not getting invoked, since it authentication object has present already. dont know what is wrong with my configuration, thanks for you answers

Spring Security Authentication Issue

We need help with regard to Authentication using Spring Security. When we try to key in the login credentials for our application and click on submit, We are getting an invalid credentials error.
we have checked the database and the authentication details that we are using to login seems to be correct. But still getting the below exception
[DEBUG,LdapAuthenticationProvider,http-localhost%2F127.0.0.1-8080-1] Processing authentication request for user: admin
[DEBUG,FilterBasedLdapUserSearch,http-localhost%2F127.0.0.1-8080-1] Searching for user 'admin', with user search [ searchFilter: 'sAMAccountName={0}', searchBase: 'DC=ad,DC=infosys,DC=com', scope: subtree, searchTimeLimit: 0, derefLinkFlag: true ]
[INFO,SpringSecurityLdapTemplate,http-localhost%2F127.0.0.1-8080-1] Ignoring PartialResultException
[WARN,LoggerListener,http-localhost%2F127.0.0.1-8080-1] Authentication event AuthenticationFailureBadCredentialsEvent: admin; details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: DEC9042719AA53736897C4383DCF8FE8; exception: Bad credentials
[DEBUG,UsernamePasswordAuthenticationFilter,http-localhost%2F127.0.0.1-8080-1] Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
Im trying to connect to the sqlserver2008 database and trying to login.Below is the security.xml file that we are using
<http auto-config='false' realm="MaskIT Realm" access-denied-page="/403.jsp">
<intercept-url pattern="/*.htm" access="ROLE_ADMIN,ROLE_REQUESTOR,ROLE_APPROVER" />
<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<form-login login-page="/login.jsp"
authentication-failure-url="/login.jsp?login_error=1"
default-target-url="/redirect.jsp" />
<http-basic />
<intercept-url pattern="/securityService" access="IS_AUTHENTICATED_ANONYMOUSLY"
requires-channel="http" />
<logout logout-success-url="/login.jsp" />
</http>
<b:bean id="myAuthenticationProvider"
class="com.infosys.setl.himi.maskit.security.SwitchingAuthenticationProvider">
<b:constructor-arg ref="paramManager" />
<b:property name="providers">
<b:list>
<b:ref local="daoAuthenticationProvider" />
<b:ref local="ldapProvider" />
</b:list>
</b:property>
</b:bean>
<b:bean id="daoAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<b:property name="userDetailsService" ref="userDetailsService" />
<!-- <b:property name="passwordEncoder" ref="passwordEncoder" /> -->
</b:bean>
<b:bean id="userDetailsService"
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<b:property name="dataSource" ref="dataSourceMSSQL" />
<b:property name="usersByUsernameQuery">
<b:value>SELECT user_id ,password,active FROM sec_users
WHERE
user_id=?</b:value>
</b:property>
<b:property name="authoritiesByUsernameQuery">
<b:value>SELECT a.user_id AS user_id,b.roleName AS roleName FROM
sec_users a, emaskit_roles b
WHERE a.roleID = b.roleID AND
a.user_id=?</b:value>
</b:property>
</b:bean>
I would like to know how & when the sql query is getting executed for checking the authentication. Is it calling any java class( so that i can debug the code and check where it is failing) to perform the check or is it done internally by the Spring framework.
Please Assist. Thanks in Advance
What brothers me is that you logfile shows that you try to use an Ldap for authentication (LdapAuthenticationProvider) but you xml file shows that you try to use a DaoAuthenticationProvider.
I really think you massed up you deployment, either you looked/deployed on the wrong server or you did not deployed the (actual version) application at all.
In addition there is a mistake in you configuration: you have to tell spring security to use your daoAuthenticationProvider:
add this:
<authentication-manager alias="authenticationManager">
<authentication-provider ref="daoAuthenticationProvider"/>
</authentication-manager>

Resources