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