001package com.nimbusds.oauth2.sdk.auth;
002
003
004import java.util.Map;
005
006import com.nimbusds.oauth2.sdk.ParseException;
007import com.nimbusds.oauth2.sdk.SerializeException;
008import com.nimbusds.oauth2.sdk.http.CommonContentTypes;
009import com.nimbusds.oauth2.sdk.http.HTTPRequest;
010import 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 */
024public 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}