forked from authlete/java-oauth-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIntrospectionEndpoint.java
119 lines (106 loc) · 4.66 KB
/
IntrospectionEndpoint.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
* Copyright (C) 2017-2023 Authlete, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package com.authlete.jaxrs.server.api;
import javax.ws.rs.Consumes;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.authlete.common.api.AuthleteApiFactory;
import com.authlete.common.web.BasicCredentials;
import com.authlete.jaxrs.BaseIntrospectionEndpoint;
import com.authlete.jaxrs.IntrospectionRequestHandler.Params;
import com.authlete.jaxrs.server.db.ResourceServerDao;
import com.authlete.jaxrs.server.db.ResourceServerEntity;
/**
* An implementation of introspection endpoint (<a href=
* "http://tools.ietf.org/html/rfc7662">RFC 7662</a>).
*
* @see <a href="http://tools.ietf.org/html/rfc7662"
* >RFC 7662, OAuth 2.0 Token Introspection</a>
*
* @author Takahiko Kawasaki
* @author Hideki Ikeda
*/
@Path("/api/introspection")
public class IntrospectionEndpoint extends BaseIntrospectionEndpoint
{
/**
* The introspection endpoint.
*
* @see <a href="http://tools.ietf.org/html/rfc7662#section-2.1"
* >RFC 7662, 2.1. Introspection Request</a>
*/
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response post(
@HeaderParam(HttpHeaders.AUTHORIZATION) String authorization,
@HeaderParam(HttpHeaders.ACCEPT) String accept,
MultivaluedMap<String, String> parameters)
{
// "2.1. Introspection Request" in RFC 7662 says as follows:
//
// To prevent token scanning attacks, the endpoint MUST also require
// some form of authorization to access this endpoint, such as client
// authentication as described in OAuth 2.0 [RFC6749] or a separate
// OAuth 2.0 access token such as the bearer token described in OAuth
// 2.0 Bearer Token Usage [RFC6750]. The methods of managing and
// validating these authentication credentials are out of scope of this
// specification.
//
// Therefore, this API must be protected in some way or other.
// Basic Authentication and Bearer Token are typical means, and
// both use the value of the 'Authorization' header.
BasicCredentials credentials = BasicCredentials.parse(authorization);
// Fetch the information about the resource server from DB.
ResourceServerEntity rsEntity = ResourceServerDao.get(credentials.getUserId());
// If failed to authenticate the resource server.
if (authenticateResourceServer(rsEntity, credentials) == false)
{
// Return "401 Unauthorized".
return Response.status(Status.UNAUTHORIZED).build();
}
// Build a Param object to call the request handler.
Params params = buildParams(parameters, accept, rsEntity);
// Handle the introspection request.
return handle(AuthleteApiFactory.getDefaultApi(), params);
}
private Params buildParams(
MultivaluedMap<String, String> parameters, String accept, ResourceServerEntity rsEntity)
{
return new Params()
.setParameters(parameters)
.setHttpAcceptHeader(accept)
.setRsUri(rsEntity.getUri())
.setIntrospectionSignAlg(rsEntity.getIntrospectionSignAlg())
.setIntrospectionEncryptionAlg(rsEntity.getIntrospectionEncryptionAlg())
.setIntrospectionEncryptionEnc(rsEntity.getIntrospectionEncryptionEnc())
.setPublicKeyForEncryption(rsEntity.getPublicKeyForIntrospectionResponseEncryption())
.setSharedKeyForSign(rsEntity.getSharedKeyForIntrospectionResponseSign())
.setSharedKeyForEncryption(rsEntity.getSharedKeyForIntrospectionResponseEncryption());
}
private boolean authenticateResourceServer(
ResourceServerEntity rsEntity, BasicCredentials credentials)
{
return rsEntity != null &&
rsEntity.getSecret().equals(credentials.getPassword());
}
}