I have manage to create REST API with spring mvc. My purpose was about to protect a resource with JWToken. Now i am trying to write three Test :
1. Get the Token with granted user/password Authentication Fail => test:OK
2. Get the Token with not granted user/password Authentication success => test:OK
3. Get the protected resource without providing the Token => test:fail because my rest service give the protected resource ....
Here is my REST controller:
@Component @RestController @RequestMapping(value="/protected") public class HelloWorldRest { /** * Logger */ private static final Logger LOG = LoggerFactory .getLogger(HelloWorldRest.class); private static final String template = "Hello, %s!"; private final AtomicLong counter = new AtomicLong(); /** * permet de générer un token * * @param idFonc */ @RequestMapping(value="/greeting/{name}") public Greeting greeting(@PathVariable String name) { LOG.info("Fonction greeting : "+name); return new Greeting(counter.incrementAndGet(), String.format(template, name+ ", je suis Mister Toto")); } }
Here is my test case:
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = { "/tokenEndPointsTests.xml" }) public class tokenEndPointsTests { @Autowired private WebApplicationContext context; private MockMvc mockMvc; @Autowired private Filter resourceServerFilter; @Before public void setup() { // mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); mockMvc = MockMvcBuilders.webAppContextSetup(context).addFilter(resourceServerFilter,"/protected").build(); } @Test public void testgetToken() throws Exception { UsernamePasswordAuthenticationToken principal = new UsernamePasswordAuthenticationToken( new Principal() { @Override public String getName() { return "user"; } }, null, null); MvcResult mvcresult = mockMvc .perform( get("/oauth/token").param("client_id", "user") .param("client_secret", "password") .param("grant_type", "password") .param("username", "user") .param("password", "password") .principal(principal)).andDo(print()) .andExpect(status().isOk()).andReturn(); MockHttpServletRequest mockhttp = mvcresult.getRequest(); System.out.println(mockhttp.toString()); } @Test public void testgetTokenEchec() throws Exception { UsernamePasswordAuthenticationToken principal = new UsernamePasswordAuthenticationToken( new Principal() { @Override public String getName() { // c'est le nom de l'user ... return "user1"; } }, null, null); MvcResult mvcresult = mockMvc .perform( get("/oauth/token").param("client_id", "user") .param("client_secret", "password") .param("grant_type", "password") .param("username", "user") .param("password", "password") .principal(principal)).andDo(print()) .andExpect(status().isUnauthorized()).andReturn(); MockHttpServletRequest mockhttp = mvcresult.getRequest(); System.out.println(mockhttp.toString()); } @Test public void testgetProtectedResource() throws Exception { MvcResult mvcresult = mockMvc.perform(get("/protected/greeting/toto")) .andDo(print()).andExpect(status().isUnauthorized()) .andReturn(); } }
Here is my tokenEndPointsTests:
<?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.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config /> <context:component-scan base-package="com.sample" /> <mvc:annotation-driven /> <mvc:annotation-driven /> <sec:http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="authenticationManager"> <sec:intercept-url pattern="/oauth/token" /> <sec:http-basic entry-point-ref="clientAuthenticationEntryPoint" /> <sec:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" /> <sec:access-denied-handler ref="oauthAccessDeniedHandler" /> </sec:http> <sec:http pattern="/protected/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"> <sec:anonymous enabled="false" /> <sec:intercept-url pattern="/protected/**" /> <sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /> <sec:access-denied-handler ref="oauthAccessDeniedHandler" /> </sec:http> <bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> </bean> <bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> <property name="realmName" value="springsec/client" /> <property name="typeName" value="Basic" /> </bean> <bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"> </bean> <bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter"> <property name="authenticationManager" ref="authenticationManager" /> </bean> <sec:authentication-manager alias="authenticationManager"> <sec:authentication-provider user-service-ref="clientDetailsUserService"> </sec:authentication-provider> </sec:authentication-manager> <bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"> <constructor-arg ref="clientDetails" /> </bean> <bean id="clientDetails" class="com.sample.context.security.InMemoryClientDetailsServiceSample"> </bean> <oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices"> <oauth:password authentication-manager-ref="authenticationManager" /> </oauth:authorization-server> <oauth:resource-server id="resourceServerFilter" token-services-ref="tokenServices" /> <bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JwtTokenStore"> <constructor-arg ref="JwttokenConverter"></constructor-arg> </bean> <bean id="JwttokenConverter" class="org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter" /> <bean id="tokenServices" class="com.sample.context.security.JWTokenServices"> <property name="tokenStore" ref="tokenStore" /> <property name="supportRefreshToken" value="false" /> <property name="accessTokenValiditySeconds" value="3600"></property> <property name="clientDetailsService" ref="clientDetails" /> <property name="accessTokenEnhancer" ref="JwttokenConverter"></property> </bean> </beans>
It seem resourceServerFilter is not used during testgetProtectedResource().
Thank for reading me :).