Skip to content

Commit 1a6475d

Browse files
author
Dave Syer
committed
SECOAUTH-160: re-organize ClientDetails and AuthenticationRequest
1 parent 74e9205 commit 1a6475d

26 files changed

+376
-341
lines changed
Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
11
package org.springframework.security.oauth2.common.util;
22

33
import java.util.Arrays;
4+
import java.util.Collection;
45
import java.util.Set;
56
import java.util.TreeSet;
67

8+
import org.springframework.util.StringUtils;
9+
710
/**
811
* @author Ryan Heaton
12+
* @author Dave Syer
913
*/
10-
public class OAuth2Utils {
14+
public abstract class OAuth2Utils {
1115

12-
private OAuth2Utils() {}
16+
/**
17+
* Parses a string value into a scope.
18+
*
19+
* @param scopeValue The value of the scope.
20+
* @return The scope.
21+
*/
22+
public static Set<String> parseScope(String scopeValue) {
23+
Set<String> scope = new TreeSet<String>();
24+
if (scopeValue != null) {
25+
// the spec says the scope is separated by spaces, but Facebook uses commas, so we'll include commas, too.
26+
String[] tokens = scopeValue.split("[\\s+,]");
27+
scope.addAll(Arrays.asList(tokens));
28+
}
29+
return scope;
30+
}
1331

14-
/**
15-
* Parses a string value into a scope.
16-
*
17-
* @param scopeValue The value of the scope.
18-
* @return The scope.
19-
*/
20-
public static Set<String> parseScope(String scopeValue) {
21-
Set<String> scope = new TreeSet<String>();
22-
if (scopeValue != null) {
23-
//the spec says the scope is separated by spaces, but Facebook uses commas, so we'll include commas, too.
24-
String[] tokens = scopeValue.split("[\\s+,]");
25-
scope.addAll(Arrays.asList(tokens));
26-
}
27-
return scope;
28-
}
32+
/**
33+
* Formats a scope value into a String.
34+
*
35+
* @param scopeValue The value of the scope.
36+
* @return The scope formatted for form submission etc, or null if the input is empty
37+
*/
38+
public static String formatScope(Collection<String> scope) {
39+
return scope==null ? null : StringUtils.collectionToDelimitedString(scope, " ");
40+
}
2941
}
Lines changed: 137 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,169 @@
11
package org.springframework.security.oauth2.provider;
22

3+
import java.io.Serializable;
4+
import java.util.Collection;
5+
import java.util.Collections;
6+
import java.util.HashMap;
7+
import java.util.HashSet;
38
import java.util.Map;
49
import java.util.Set;
510

11+
import org.springframework.security.core.GrantedAuthority;
612
import org.springframework.security.oauth2.common.util.OAuth2Utils;
713

814
/**
9-
* Client token for a request for a authorization.
15+
* Base class representing a request for authorization. There are convenience methods for the well-known properties
16+
* required by the OAUth2 spec, and a set of generic parameters to allow for extensions.
1017
*
1118
* @author Ryan Heaton
1219
* @author Dave Syer
1320
*/
14-
public class AuthorizationRequest extends ClientToken {
21+
public class AuthorizationRequest implements Serializable {
1522

16-
private final String state;
23+
private static final String CLIENT_ID = "client_id";
1724

18-
private final String requestedRedirect;
25+
private static final String CLIENT_SECRET = "client_secret";
1926

20-
private boolean denied;
27+
private static final String STATE = "state";
2128

22-
public AuthorizationRequest(String clientId, String clientSecret, Set<String> scope, String state,
29+
private static final String SCOPE = "scope";
30+
31+
private static final String REDIRECT_URI = "redirect_uri";
32+
33+
private final Set<String> scope;
34+
35+
private final Set<String> resourceIds;
36+
37+
private final boolean denied;
38+
39+
private final Collection<GrantedAuthority> authorities;
40+
41+
private final Map<String, String> parameters = new HashMap<String, String>();
42+
43+
public AuthorizationRequest(Map<String, String> parameters) {
44+
this(parameters.get(CLIENT_ID), null, OAuth2Utils.parseScope(parameters.get("scope")), null, null, false,
45+
parameters.get(STATE), parameters.get(REDIRECT_URI));
46+
this.parameters.putAll(parameters);
47+
}
48+
49+
public AuthorizationRequest(String clientId, String clientSecret, Collection<String> scope,
50+
Collection<GrantedAuthority> authorities, Collection<String> resourceIds) {
51+
this(clientId, clientSecret, scope, authorities, resourceIds, false, null, null);
52+
}
53+
54+
private AuthorizationRequest(AuthorizationRequest copy, boolean denied) {
55+
this(copy.getClientId(), copy.getClientSecret(), copy.scope, copy.authorities, copy.resourceIds, denied, copy
56+
.getState(), copy.getRequestedRedirect());
57+
this.parameters.putAll(copy.parameters);
58+
}
59+
60+
private AuthorizationRequest(String clientId, String clientSecret, Collection<String> scope,
61+
Collection<GrantedAuthority> authorities, Collection<String> resourceIds, boolean denied, String state,
2362
String requestedRedirect) {
24-
super(clientId, clientSecret, scope);
25-
this.state = state;
26-
this.requestedRedirect = requestedRedirect;
63+
this.resourceIds = resourceIds == null ? null : Collections.unmodifiableSet(new HashSet<String>(resourceIds));
64+
this.scope = scope == null ? Collections.<String> emptySet() : Collections.unmodifiableSet(new HashSet<String>(
65+
scope));
66+
this.authorities = authorities == null ? null : new HashSet<GrantedAuthority>(authorities);
67+
this.denied = denied;
68+
parameters.put(CLIENT_ID, clientId);
69+
parameters.put(CLIENT_SECRET, clientSecret);
70+
parameters.put(STATE, state);
71+
parameters.put(REDIRECT_URI, requestedRedirect);
72+
parameters.put(SCOPE, OAuth2Utils.formatScope(scope));
2773
}
2874

29-
public AuthorizationRequest(Map<String, String> parameters) {
30-
this(parameters.get("client_id"), null, OAuth2Utils.parseScope(parameters.get("scope")), parameters
31-
.get("state"), parameters.get("redirect_uri"));
75+
public Map<String, String> getParameters() {
76+
return Collections.unmodifiableMap(parameters);
3277
}
3378

34-
public String getRequestedRedirect() {
35-
return requestedRedirect;
79+
public String getClientId() {
80+
return parameters.get(CLIENT_ID);
3681
}
3782

38-
public String getState() {
39-
return state;
83+
public String getClientSecret() {
84+
return parameters.get(CLIENT_SECRET);
85+
}
86+
87+
public Set<String> getScope() {
88+
return this.scope;
89+
}
90+
91+
public Set<String> getResourceIds() {
92+
return resourceIds;
93+
}
94+
95+
public Collection<GrantedAuthority> getAuthorities() {
96+
return authorities;
97+
}
98+
99+
public boolean isAuthenticated() {
100+
return !denied;
40101
}
41102

42103
public boolean isDenied() {
43104
return denied;
44105
}
45106

46-
// TODO: make this immutable
47-
public void setDenied(boolean denied) {
48-
this.denied = denied;
49-
setApproved(!denied);
107+
public AuthorizationRequest denied(boolean denied) {
108+
return new AuthorizationRequest(this, denied);
109+
}
110+
111+
public String getState() {
112+
return parameters.get(STATE);
113+
}
114+
115+
public String getRequestedRedirect() {
116+
return parameters.get(REDIRECT_URI);
117+
}
118+
119+
@Override
120+
public int hashCode() {
121+
final int prime = 31;
122+
int result = 1;
123+
result = prime * result + ((authorities == null) ? 0 : authorities.hashCode());
124+
result = prime * result + (denied ? 1231 : 1237);
125+
result = prime * result + ((parameters == null) ? 0 : parameters.hashCode());
126+
result = prime * result + ((resourceIds == null) ? 0 : resourceIds.hashCode());
127+
result = prime * result + ((scope == null) ? 0 : scope.hashCode());
128+
return result;
129+
}
130+
131+
@Override
132+
public boolean equals(Object obj) {
133+
if (this == obj)
134+
return true;
135+
if (obj == null)
136+
return false;
137+
if (getClass() != obj.getClass())
138+
return false;
139+
AuthorizationRequest other = (AuthorizationRequest) obj;
140+
if (authorities == null) {
141+
if (other.authorities != null)
142+
return false;
143+
}
144+
else if (!authorities.equals(other.authorities))
145+
return false;
146+
if (denied != other.denied)
147+
return false;
148+
if (parameters == null) {
149+
if (other.parameters != null)
150+
return false;
151+
}
152+
else if (!parameters.equals(other.parameters))
153+
return false;
154+
if (resourceIds == null) {
155+
if (other.resourceIds != null)
156+
return false;
157+
}
158+
else if (!resourceIds.equals(other.resourceIds))
159+
return false;
160+
if (scope == null) {
161+
if (other.scope != null)
162+
return false;
163+
}
164+
else if (!scope.equals(other.scope))
165+
return false;
166+
return true;
50167
}
51168

52169
}

spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/BaseClientDetails.java

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package org.springframework.security.oauth2.provider;
22

3+
import java.util.ArrayList;
34
import java.util.Arrays;
5+
import java.util.Collection;
46
import java.util.Collections;
7+
import java.util.HashSet;
8+
import java.util.LinkedHashSet;
59
import java.util.List;
10+
import java.util.Set;
611

712
import org.springframework.security.core.GrantedAuthority;
813
import org.springframework.security.core.authority.AuthorityUtils;
@@ -17,38 +22,44 @@
1722
public class BaseClientDetails implements ClientDetails {
1823

1924
private String clientId;
25+
2026
private String clientSecret;
21-
private List<String> scope = Collections.emptyList();
22-
private List<String> resourceIds = Collections.emptyList();
23-
private List<String> authorizedGrantTypes = Collections.emptyList();
27+
28+
private Set<String> scope = Collections.emptySet();
29+
30+
private Set<String> resourceIds = Collections.emptySet();
31+
32+
private Set<String> authorizedGrantTypes = Collections.emptySet();
33+
2434
private String registeredRedirectUri;
35+
2536
private List<GrantedAuthority> authorities = Collections.emptyList();
2637

2738
public BaseClientDetails() {
2839
}
2940

30-
public BaseClientDetails(String commaSeparatedResourceIds, String commaSeparatedScopes, String commaSeparatedAuthorizedGrantTypes,
31-
String commaSeparatedAuthorities) {
41+
public BaseClientDetails(String commaSeparatedResourceIds, String commaSeparatedScopes,
42+
String commaSeparatedAuthorizedGrantTypes, String commaSeparatedAuthorities) {
3243

3344
if (StringUtils.hasText(commaSeparatedResourceIds)) {
34-
List<String> resourceIds = Arrays.asList(StringUtils.commaDelimitedListToStringArray(commaSeparatedResourceIds));
45+
Set<String> resourceIds = StringUtils.commaDelimitedListToSet(commaSeparatedResourceIds);
3546
if (!resourceIds.isEmpty()) {
3647
this.resourceIds = resourceIds;
3748
}
3849
}
3950

4051
if (StringUtils.hasText(commaSeparatedScopes)) {
41-
List<String> scopeList = Arrays.asList(StringUtils.commaDelimitedListToStringArray(commaSeparatedScopes));
52+
Set<String> scopeList = StringUtils.commaDelimitedListToSet(commaSeparatedScopes);
4253
if (!scopeList.isEmpty()) {
4354
this.scope = scopeList;
4455
}
4556
}
4657

4758
if (StringUtils.hasText(commaSeparatedAuthorizedGrantTypes)) {
48-
this.authorizedGrantTypes = Arrays.asList(StringUtils
49-
.commaDelimitedListToStringArray(commaSeparatedAuthorizedGrantTypes));
50-
} else {
51-
this.authorizedGrantTypes = Arrays.asList("authorization_code", "refresh_token");
59+
this.authorizedGrantTypes = StringUtils.commaDelimitedListToSet(commaSeparatedAuthorizedGrantTypes);
60+
}
61+
else {
62+
this.authorizedGrantTypes = new HashSet<String>(Arrays.asList("authorization_code", "refresh_token"));
5263
}
5364

5465
if (StringUtils.hasText(commaSeparatedAuthorities)) {
@@ -80,28 +91,28 @@ public boolean isScoped() {
8091
return this.scope != null && !this.scope.isEmpty();
8192
}
8293

83-
public List<String> getScope() {
94+
public Set<String> getScope() {
8495
return scope;
8596
}
8697

87-
public void setScope(List<String> scope) {
88-
this.scope = scope;
98+
public void setScope(Collection<String> scope) {
99+
this.scope = new LinkedHashSet<String>(scope);
89100
}
90101

91-
public List<String> getResourceIds() {
102+
public Set<String> getResourceIds() {
92103
return resourceIds;
93104
}
94105

95-
public void setResourceIds(List<String> resourceIds) {
96-
this.resourceIds = resourceIds;
106+
public void setResourceIds(Collection<String> resourceIds) {
107+
this.resourceIds = new LinkedHashSet<String>(resourceIds);
97108
}
98109

99-
public List<String> getAuthorizedGrantTypes() {
110+
public Set<String> getAuthorizedGrantTypes() {
100111
return authorizedGrantTypes;
101112
}
102113

103-
public void setAuthorizedGrantTypes(List<String> authorizedGrantTypes) {
104-
this.authorizedGrantTypes = authorizedGrantTypes;
114+
public void setAuthorizedGrantTypes(Collection<String> authorizedGrantTypes) {
115+
this.authorizedGrantTypes = new LinkedHashSet<String>(authorizedGrantTypes);
105116
}
106117

107118
public String getRegisteredRedirectUri() {
@@ -112,11 +123,11 @@ public void setRegisteredRedirectUri(String registeredRedirectUri) {
112123
this.registeredRedirectUri = registeredRedirectUri;
113124
}
114125

115-
public List<GrantedAuthority> getAuthorities() {
126+
public Collection<GrantedAuthority> getAuthorities() {
116127
return authorities;
117128
}
118129

119-
public void setAuthorities(List<GrantedAuthority> authorities) {
120-
this.authorities = authorities;
130+
public void setAuthorities(Collection<GrantedAuthority> authorities) {
131+
this.authorities = new ArrayList<GrantedAuthority>(authorities);
121132
}
122133
}

0 commit comments

Comments
 (0)