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