001package com.nimbusds.oauth2.sdk.auth; 002 003 004import java.util.Map; 005 006import org.apache.commons.lang3.StringUtils; 007 008import com.nimbusds.oauth2.sdk.ParseException; 009import com.nimbusds.oauth2.sdk.SerializeException; 010import com.nimbusds.oauth2.sdk.http.CommonContentTypes; 011import com.nimbusds.oauth2.sdk.http.HTTPRequest; 012import com.nimbusds.oauth2.sdk.id.ClientID; 013import com.nimbusds.oauth2.sdk.util.URLUtils; 014 015 016/** 017 * Base abstract class for client authentication at the Token endpoint. 018 * 019 * <p>Related specifications: 020 * 021 * <ul> 022 * <li>OAuth 2.0 (RFC 6749), section 2.3. 023 * </ul> 024 */ 025public abstract class ClientAuthentication { 026 027 028 /** 029 * The client authentication method. 030 */ 031 private final ClientAuthenticationMethod method; 032 033 034 /** 035 * The client ID. 036 */ 037 private final ClientID clientID; 038 039 040 /** 041 * Creates a new abstract client authentication. 042 * 043 * @param method The client authentication method. Must not be 044 * {@code null}. 045 * @param clientID The client identifier. Must not be {@code null}. 046 */ 047 protected ClientAuthentication(final ClientAuthenticationMethod method, final ClientID clientID) { 048 049 if (method == null) 050 throw new IllegalArgumentException("The client authentication method must not be null"); 051 052 this.method = method; 053 054 055 if (clientID == null) 056 throw new IllegalArgumentException("The client identifier must not be null"); 057 058 this.clientID = clientID; 059 } 060 061 062 /** 063 * Gets the client authentication method. 064 * 065 * @return The client authentication method. 066 */ 067 public ClientAuthenticationMethod getMethod() { 068 069 return method; 070 } 071 072 073 /** 074 * Gets the client identifier. 075 * 076 * @return The client identifier. 077 */ 078 public ClientID getClientID() { 079 080 return clientID; 081 } 082 083 084 /** 085 * Parses the specified HTTP request for a supported client 086 * authentication (see {@link ClientAuthenticationMethod}). This method 087 * is intended to aid parsing of authenticated 088 * {@link com.nimbusds.oauth2.sdk.TokenRequest}s. 089 * 090 * @param httpRequest The HTTP request to parse. Must not be 091 * {@code null}. 092 * 093 * @return The client authentication method, {@code null} if none or 094 * the method is not supported. 095 * 096 * @throws ParseException If the inferred client authentication 097 * couldn't be parsed. 098 */ 099 public static ClientAuthentication parse(final HTTPRequest httpRequest) 100 throws ParseException { 101 102 // Check for client secret basic 103 if (httpRequest.getAuthorization() != null && 104 httpRequest.getAuthorization().startsWith("Basic")) 105 106 return ClientSecretBasic.parse(httpRequest); 107 108 // The other methods require HTTP POST with URL-encoded params 109 if (httpRequest.getMethod() != HTTPRequest.Method.POST && 110 ! httpRequest.getContentType().match(CommonContentTypes.APPLICATION_URLENCODED)) 111 return null; 112 113 114 String query = httpRequest.getQuery(); 115 116 if (query == null) 117 return null; 118 119 Map<String,String> params = URLUtils.parseParameters(query); 120 121 // We have client secret post 122 if (StringUtils.isNotBlank(params.get("client_id")) && StringUtils.isNotBlank(params.get("client_secret"))) 123 return ClientSecretPost.parse(httpRequest); 124 125 // Do we have a signed JWT assertion? 126 if (StringUtils.isNotBlank(params.get("client_assertion")) && StringUtils.isNotBlank(params.get("client_assertion_type"))) 127 return JWTAuthentication.parse(httpRequest); 128 else 129 return null; 130 } 131 132 133 /** 134 * Applies the authentication to the specified HTTP request by setting 135 * its Authorization header and/or POST entity-body parameters 136 * (according to the implemented client authentication method). 137 * 138 * @param httpRequest The HTTP request. Must not be {@code null}. 139 * 140 * @throws SerializeException If the client authentication parameters 141 * couldn't be applied to the HTTP request. 142 */ 143 public abstract void applyTo(final HTTPRequest httpRequest) 144 throws SerializeException; 145}