Hello:
I'm trying to figure out how best to handle token related exceptions, both those possible within the framework itself (token not found, has expired), as well as others I'd like to add (source IP address changed, token has been used too many times, token usage suspicious and captcha is required etc.).
In addition, my RESTful APIs are being invoked cross-domain via JSONP. Rather than making use of Ajax and being able to return appropriate HTTP status codes, JSONP performed within JavaScript simply times out if the callback function is not invoked. This is the case when the API fails for any reason.
It seems I must always return a response, and indicate the status within, good or bad. So, I need to deal with the bad so I can return the callback function wrapped status so the client will know what's up.
I think this crosses the boundary between Spring Security and the OAuth extension. First off, my application has no end user data. I'm using client credentials so that a tenant application can acquire a bearer token on behalf of a user agent (browser for now), which then provides the token to access the APIs, and identify the tenant. There is tenant specific content, as well as rules applied to the shared content.
In terms of dealing with Spring Security exceptions, I see ExceptionMappingAuthenticationFailureHandler comes up. This looks very useful; I could forward to a JSP that will return the response needed. But, I've only seen a custom implementation being wired in via authentication-failure-handler-ref attribute of the form-login element. I have no end users, and thus no form-login:
Note my application is both an authorization server and a resource (API) server. I added the tokenStore and clientDetailsService beans from a different context file just so everything is listed above. Can resource-server be configured instead of login-form? Do I have to create my own subclass of the resource server filter to get the hooks I need?Code:<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.1.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd"> <!-- Note that ISEC is both an OAuth authorization server as well as the resource server. --> <http auto-config="true" create-session="never" access-decision-manager-ref="accessDecisionManager"> <intercept-url pattern="/api/rest/v1/client/**" access="ROLE_CLIENT,SCOPE_READ" /> <intercept-url pattern="/api/rest/v1/partner/**" access="ROLE_PARTNER,SCOPE_WRITE" /> <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/oauth/authorize" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/oauth/**" access="ROLE_CLIENT,ROLE_PARTNER" /> <custom-filter ref="resourceServerFilter" after="EXCEPTION_TRANSLATION_FILTER"/> </http> <oauth:resource-server id="resourceServerFilter" resource-id="isecApi" token-services-ref="tokenServices"/> <oauth:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices"> <oauth:client-credentials /> </oauth:authorization-server> <authentication-manager/> <beans:bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.RandomValueTokenServices"> <beans:property name="tokenStore" ref="tokenStore"/> <beans:property name="supportRefreshToken" value="false" /> </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> <bean id="clientDetailsService" class="com.mycompany.isec.service.cassandra.CassandraClientDetailsService"> <constructor-arg ref="isecTenantEm"/> </bean> <bean id="tokenStore" class="com.mycompany.isec.service.cassandra.CassandraTokenStore"> <constructor-arg ref="isecSecurityEm"/> <constructor-arg ref="clientDetailsService"/> </bean> </beans:beans>
I am using 1.0.0.M5.
Thanks,
Jeff


Reply With Quote
