Skip to content

Commit b736928

Browse files
authored
Scope handling (#14)
* Improve validating scopes
1 parent cf461de commit b736928

File tree

4 files changed

+33
-34
lines changed

4 files changed

+33
-34
lines changed

kotlin-oauth2-server-core/src/main/java/nl/myndocs/oauth2/Oauth2TokenService.kt

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package nl.myndocs.oauth2
22

33
import nl.myndocs.oauth2.authenticator.Authenticator
44
import nl.myndocs.oauth2.authenticator.IdentityScopeVerifier
5+
import nl.myndocs.oauth2.client.Client
56
import nl.myndocs.oauth2.client.ClientService
67
import nl.myndocs.oauth2.exception.*
8+
import nl.myndocs.oauth2.identity.Identity
79
import nl.myndocs.oauth2.identity.IdentityService
810
import nl.myndocs.oauth2.identity.UserInfo
911
import nl.myndocs.oauth2.request.*
@@ -59,15 +61,7 @@ class Oauth2TokenService(
5961
requestedScopes = requestedClient.clientScopes
6062
}
6163

62-
val scopesAllowed = scopesAllowed(requestedClient.clientScopes, requestedScopes)
63-
64-
if (!scopesAllowed) {
65-
throw InvalidScopeException(requestedScopes.minus(requestedClient.clientScopes))
66-
}
67-
68-
if (!identityService.validScopes(requestedClient, requestedIdentity, requestedScopes)) {
69-
throw InvalidScopeException(requestedScopes)
70-
}
64+
validateScopes(requestedClient, requestedIdentity, requestedScopes)
7165

7266
val accessToken = accessTokenConverter.convertToToken(
7367
requestedIdentity.username,
@@ -186,16 +180,7 @@ class Oauth2TokenService(
186180
requestedScopes = clientOf.clientScopes
187181
}
188182

189-
val scopesAllowed = identityScopeVerifier?.validScopes(clientOf, identityOf, requestedScopes)
190-
?: scopesAllowed(clientOf.clientScopes, requestedScopes)
191-
192-
if (!scopesAllowed) {
193-
throw InvalidScopeException(requestedScopes.minus(clientOf.clientScopes))
194-
}
195-
196-
if (!identityService.validScopes(clientOf, identityOf, requestedScopes)) {
197-
throw InvalidScopeException(requestedScopes)
198-
}
183+
validateScopes(clientOf, identityOf, requestedScopes, identityScopeVerifier)
199184

200185
val codeToken = codeTokenConverter.convertToToken(
201186
identityOf.username,
@@ -250,15 +235,7 @@ class Oauth2TokenService(
250235
requestedScopes = clientOf.clientScopes
251236
}
252237

253-
val scopesAllowed = identityScopeVerifier?.validScopes(clientOf, identityOf, requestedScopes)
254-
?: scopesAllowed(clientOf.clientScopes, requestedScopes)
255-
if (!scopesAllowed) {
256-
throw InvalidScopeException(requestedScopes.minus(clientOf.clientScopes))
257-
}
258-
259-
if (!identityService.validScopes(clientOf, identityOf, requestedScopes)) {
260-
throw InvalidScopeException(requestedScopes)
261-
}
238+
validateScopes(clientOf, identityOf, requestedScopes, identityScopeVerifier)
262239

263240
val accessToken = accessTokenConverter.convertToToken(
264241
identityOf.username,
@@ -272,6 +249,25 @@ class Oauth2TokenService(
272249
return accessToken
273250
}
274251

252+
private fun validateScopes(
253+
client: Client,
254+
identity: Identity,
255+
requestedScopes: Set<String>,
256+
identityScopeVerifier: IdentityScopeVerifier? = null) {
257+
val scopesAllowed = scopesAllowed(client.clientScopes, requestedScopes)
258+
if (!scopesAllowed) {
259+
throw InvalidScopeException(requestedScopes.minus(client.clientScopes))
260+
}
261+
262+
val allowedScopes = identityScopeVerifier?.allowedScopes(client, identity, requestedScopes)
263+
?: identityService.allowedScopes(client, identity, requestedScopes)
264+
265+
val ivalidScopes = requestedScopes.minus(allowedScopes)
266+
if (ivalidScopes.isNotEmpty()) {
267+
throw InvalidScopeException(ivalidScopes)
268+
}
269+
}
270+
275271
override fun userInfo(accessToken: String): UserInfo {
276272
val storedAccessToken = tokenStore.accessToken(accessToken)!!
277273
val client = clientService.clientOf(storedAccessToken.clientId)!!

kotlin-oauth2-server-core/src/main/java/nl/myndocs/oauth2/authenticator/IdentityScopeVerifier.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ import nl.myndocs.oauth2.client.Client
44
import nl.myndocs.oauth2.identity.Identity
55

66
interface IdentityScopeVerifier {
7-
fun validScopes(forClient: Client, identity: Identity, scopes: Set<String>): Boolean
7+
/**
8+
* Validate which scopes are allowed. Leave out the scopes which are not allowed
9+
*/
10+
fun allowedScopes(forClient: Client, identity: Identity, scopes: Set<String>): Set<String>
811
}

kotlin-oauth2-server-core/src/test/java/nl/myndocs/oauth2/PasswordGrantTokenServiceTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ internal class PasswordGrantTokenServiceTest {
7171
every { clientService.validClient(client, clientSecret) } returns true
7272
every { identityService.identityOf(client, username) } returns identity
7373
every { identityService.validCredentials(client, identity, password) } returns true
74-
every { identityService.validScopes(client, identity, requestScopes) } returns true
74+
every { identityService.allowedScopes(client, identity, requestScopes) } returns scopes
7575
every { refreshTokenConverter.convertToToken(username, clientId, requestScopes) } returns refreshToken
7676
every { accessTokenConverter.convertToToken(username, clientId, requestScopes, refreshToken) } returns accessToken
7777

@@ -162,7 +162,7 @@ internal class PasswordGrantTokenServiceTest {
162162
every { clientService.validClient(client, clientSecret) } returns true
163163
every { identityService.identityOf(client, username) } returns identity
164164
every { identityService.validCredentials(client, identity, password) } returns true
165-
every { identityService.validScopes(client, identity, scopes) } returns false
165+
every { identityService.allowedScopes(client, identity, scopes) } returns setOf()
166166

167167
assertThrows(
168168
InvalidScopeException::class.java
@@ -178,7 +178,7 @@ internal class PasswordGrantTokenServiceTest {
178178
every { clientService.validClient(client, clientSecret) } returns true
179179
every { identityService.identityOf(client, username) } returns identity
180180
every { identityService.validCredentials(client, identity, password) } returns true
181-
every { identityService.validScopes(client, identity, scopes) } returns false
181+
every { identityService.allowedScopes(client, identity, scopes) } returns scopes
182182

183183
assertThrows(
184184
InvalidScopeException::class.java
@@ -205,7 +205,7 @@ internal class PasswordGrantTokenServiceTest {
205205
every { clientService.validClient(client, clientSecret) } returns true
206206
every { identityService.identityOf(client, username) } returns identity
207207
every { identityService.validCredentials(client, identity, password) } returns true
208-
every { identityService.validScopes(client, identity, requestScopes) } returns true
208+
every { identityService.allowedScopes(client, identity, requestScopes) } returns requestScopes
209209
every { refreshTokenConverter.convertToToken(username, clientId, requestScopes) } returns refreshToken
210210
every { accessTokenConverter.convertToToken(username, clientId, requestScopes, refreshToken) } returns accessToken
211211

kotlin-oauth2-server-identity-inmemory/src/main/java/nl/myndocs/oauth2/identity/inmemory/InMemoryIdentity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class InMemoryIdentity : IdentityService {
2727
)
2828
}
2929

30-
override fun validScopes(forClient: Client, identity: Identity, scopes: Set<String>) = true
30+
override fun allowedScopes(forClient: Client, identity: Identity, scopes: Set<String>) = scopes
3131

3232
override fun validCredentials(forClient: Client, identity: Identity, password: String): Boolean =
3333
findConfiguration(identity.username)!!.password == password

0 commit comments

Comments
 (0)