001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.openid.connect.sdk; 019 020 021import com.nimbusds.common.contenttype.ContentType; 022import com.nimbusds.oauth2.sdk.ParseException; 023import com.nimbusds.oauth2.sdk.ProtectedResourceRequest; 024import com.nimbusds.oauth2.sdk.SerializeException; 025import com.nimbusds.oauth2.sdk.http.HTTPRequest; 026import com.nimbusds.oauth2.sdk.token.AccessToken; 027import com.nimbusds.oauth2.sdk.util.URLUtils; 028import net.jcip.annotations.Immutable; 029 030import java.net.URI; 031import java.util.Collections; 032import java.util.HashMap; 033import java.util.List; 034import java.util.Map; 035 036 037/** 038 * UserInfo request. Used to retrieve the consented claims about the end-user. 039 * 040 * <p>Example HTTP GET request with a Bearer token: 041 * 042 * <pre> 043 * GET /userinfo HTTP/1.1 044 * Host: server.example.com 045 * Authorization: Bearer Eabeeduphee3aiviehahreacaoNg2thu 046 * </pre> 047 * 048 * <p>Example HTTP GET request with a DPoP token and proof: 049 * 050 * <pre> 051 * GET /userinfo HTTP/1.1 052 * Host: server.example.com 053 * Authorization: DPoP jo4kahphoh1ath4INaochohLeeshaiyo 054 * DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik... 055 * </pre> 056 * 057 * <p>Related specifications: 058 * 059 * <ul> 060 * <li>OpenID Connect Core 1.0, section 5.3.1. 061 * <li>OAuth 2.0 Bearer Token Usage (RFC6750), section 2. 062 * <li>OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer 063 * (DPoP) (RFC 9449), section 7. 064 * </ul> 065 */ 066@Immutable 067public class UserInfoRequest extends ProtectedResourceRequest { 068 069 070 /** 071 * The HTTP method. 072 */ 073 private final HTTPRequest.Method httpMethod; 074 075 076 /** 077 * Creates a new UserInfo HTTP GET request. 078 * 079 * @param uri The URI of the UserInfo endpoint. May be 080 * {@code null} if the {@link #toHTTPRequest} method 081 * will not be used. 082 * @param accessToken An access token for the request. Must not be 083 * {@code null}. 084 */ 085 public UserInfoRequest(final URI uri, final AccessToken accessToken) { 086 087 this(uri, HTTPRequest.Method.GET, accessToken); 088 } 089 090 091 /** 092 * Creates a new UserInfo request. 093 * 094 * @param uri The URI of the UserInfo endpoint. May be 095 * {@code null} if the {@link #toHTTPRequest} method 096 * will not be used. 097 * @param httpMethod The HTTP method. Must be HTTP GET or POST and not 098 * {@code null}. 099 * @param accessToken An access token for the request. Must not be 100 * {@code null}. 101 */ 102 public UserInfoRequest(final URI uri, final HTTPRequest.Method httpMethod, final AccessToken accessToken) { 103 104 super(uri, accessToken); 105 106 if (httpMethod == null) 107 throw new IllegalArgumentException("The HTTP method must not be null"); 108 109 this.httpMethod = httpMethod; 110 111 112 if (accessToken == null) 113 throw new IllegalArgumentException("The access token must not be null"); 114 } 115 116 117 /** 118 * Gets the HTTP method for this UserInfo request. 119 * 120 * @return The HTTP method. 121 */ 122 public HTTPRequest.Method getMethod() { 123 124 return httpMethod; 125 } 126 127 128 @Override 129 public HTTPRequest toHTTPRequest() { 130 131 if (getEndpointURI() == null) 132 throw new SerializeException("The endpoint URI is not specified"); 133 134 HTTPRequest httpRequest = new HTTPRequest(httpMethod, getEndpointURI()); 135 136 switch (httpMethod) { 137 138 case GET: 139 httpRequest.setAuthorization(getAccessToken().toAuthorizationHeader()); 140 break; 141 142 case POST: 143 httpRequest.setEntityContentType(ContentType.APPLICATION_URLENCODED); 144 Map<String, List<String>> params = new HashMap<>(); 145 params.put("access_token", Collections.singletonList(getAccessToken().getValue())); 146 httpRequest.setBody(URLUtils.serializeParameters(params)); 147 break; 148 149 default: 150 throw new SerializeException("Unexpected HTTP method: " + httpMethod); 151 } 152 153 return httpRequest; 154 } 155 156 157 /** 158 * Parses the specified HTTP request for a UserInfo request. 159 * 160 * @param httpRequest The HTTP request. Must not be {@code null}. 161 * 162 * @return The UserInfo request. 163 * 164 * @throws ParseException If the HTTP request couldn't be parsed to a 165 * UserInfo request. 166 */ 167 public static UserInfoRequest parse(final HTTPRequest httpRequest) 168 throws ParseException { 169 170 return new UserInfoRequest( 171 httpRequest.getURI(), 172 httpRequest.getMethod(), 173 AccessToken.parse(httpRequest) 174 ); 175 } 176}