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