View Javadoc

1   /*
2    * Copyright 2006-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5    * the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10   * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11   * specific language governing permissions and limitations under the License.
12   */
13  package org.springframework.security.oauth2.common;
14  
15  import java.io.IOException;
16  import java.util.Date;
17  import java.util.LinkedHashMap;
18  import java.util.Map;
19  import java.util.Set;
20  
21  import org.codehaus.jackson.JsonParseException;
22  import org.codehaus.jackson.JsonParser;
23  import org.codehaus.jackson.JsonProcessingException;
24  import org.codehaus.jackson.JsonToken;
25  import org.codehaus.jackson.map.DeserializationContext;
26  import org.codehaus.jackson.map.JsonDeserializer;
27  import org.codehaus.jackson.map.deser.StdDeserializer;
28  import org.springframework.security.oauth2.common.util.OAuth2Utils;
29  
30  /**
31   * <p>
32   * Provides the ability to deserialize JSON response into an {@link OAuth2AccessToken} with jackson by implementing
33   * {@link JsonDeserializer}.
34   * </p>
35   * <p>
36   * The expected format of the access token is defined by <a
37   * href="http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-5.1">Successful Response</a>.
38   * </p>
39   *
40   * @author Rob Winch
41   * @see OAuth2AccessTokenJackson1Serializer
42   */
43  @SuppressWarnings("deprecation")
44  public final class OAuth2AccessTokenJackson1Deserializer extends StdDeserializer<OAuth2AccessToken> {
45  
46  	public OAuth2AccessTokenJackson1Deserializer() {
47  		super(OAuth2AccessToken.class);
48  	}
49  
50  	@Override
51  	public OAuth2AccessToken deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
52  			JsonProcessingException {
53  
54  		String tokenValue = null;
55  		String tokenType = null;
56  		String refreshToken = null;
57  		Long expiresIn = null;
58  		Set<String> scope = null;
59  		Map<String, Object> additionalInformation = new LinkedHashMap<String, Object>();
60  
61  		// TODO What should occur if a parameter exists twice
62  		while (jp.nextToken() != JsonToken.END_OBJECT) {
63  			String name = jp.getCurrentName();
64  			jp.nextToken();
65  			if (OAuth2AccessToken.ACCESS_TOKEN.equals(name)) {
66  				tokenValue = jp.getText();
67  			}
68  			else if (OAuth2AccessToken.TOKEN_TYPE.equals(name)) {
69  				tokenType = jp.getText();
70  			}
71  			else if (OAuth2AccessToken.REFRESH_TOKEN.equals(name)) {
72  				refreshToken = jp.getText();
73  			}
74  			else if (OAuth2AccessToken.EXPIRES_IN.equals(name)) {
75  				try {
76  					expiresIn = jp.getLongValue();
77  				} catch (JsonParseException e) {
78  					expiresIn = Long.valueOf(jp.getText());
79  				}
80  			}
81  			else if (OAuth2AccessToken.SCOPE.equals(name)) {
82  				String text = jp.getText();
83  				scope = OAuth2Utils.parseParameterList(text);
84  			} else {
85  				additionalInformation.put(name, jp.readValueAs(Object.class));
86  			}
87  		}
88  
89  		// TODO What should occur if a required parameter (tokenValue or tokenType) is missing?
90  
91  		DefaultOAuth2AccessToken accessToken = new DefaultOAuth2AccessToken(tokenValue);
92  		accessToken.setTokenType(tokenType);
93  		if (expiresIn != null) {
94  			accessToken.setExpiration(new Date(System.currentTimeMillis() + (expiresIn * 1000)));
95  		}
96  		if (refreshToken != null) {
97  			accessToken.setRefreshToken(new DefaultOAuth2RefreshToken(refreshToken));
98  		}
99  		accessToken.setScope(scope);
100 		accessToken.setAdditionalInformation(additionalInformation);
101 
102 		return accessToken;
103 	}
104 }