001/* 002 * oauth2-oidc-sdk 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.oauth2.sdk.auth; 019 020 021import java.util.Collections; 022import java.util.List; 023import java.util.Map; 024import javax.mail.internet.ContentType; 025import javax.net.ssl.SSLSocketFactory; 026 027import com.nimbusds.oauth2.sdk.SerializeException; 028import com.nimbusds.oauth2.sdk.http.CommonContentTypes; 029import com.nimbusds.oauth2.sdk.http.HTTPRequest; 030import com.nimbusds.oauth2.sdk.id.ClientID; 031import com.nimbusds.oauth2.sdk.util.URLUtils; 032 033 034/** 035 * The base abstract class for mutual TLS client authentication at the Token 036 * endpoint. 037 */ 038public abstract class TLSClientAuthentication extends ClientAuthentication { 039 040 041 /** 042 * The SSL socket factory for an outgoing HTTPS request, {@code null} 043 * to use the default one. 044 */ 045 private final SSLSocketFactory sslSocketFactory; 046 047 048 /** 049 * Creates a new abstract mutual TLS client authentication. This 050 * constructor is intended for an outgoing token request. 051 * 052 * @param method The client authentication method. Must not 053 * be {@code null}. 054 * @param clientID The client identifier. Must not be 055 * {@code null}. 056 * @param sslSocketFactory The SSL socket factory to use for the 057 * outgoing HTTPS request and to present the 058 * client certificate(s), {@code null} to use 059 * the default one. 060 */ 061 protected TLSClientAuthentication(final ClientAuthenticationMethod method, 062 final ClientID clientID, 063 final SSLSocketFactory sslSocketFactory) { 064 065 super(method, clientID); 066 this.sslSocketFactory = sslSocketFactory; 067 } 068 069 070 /** 071 * Creates a new abstract mutual TLS client authentication. This 072 * constructor is intended for a received token request. 073 * 074 * @param method The client authentication method. Must not be 075 * {@code null}. 076 * @param clientID The client identifier. Must not be {@code null}. 077 */ 078 protected TLSClientAuthentication(final ClientAuthenticationMethod method, 079 final ClientID clientID) { 080 super(method, clientID); 081 sslSocketFactory = null; 082 } 083 084 085 /** 086 * Returns the SSL socket factory to use for an outgoing HTTPS request 087 * and to present the client certificate(s). 088 * 089 * @return The SSL socket factory, {@code null} to use the default one. 090 */ 091 public SSLSocketFactory getSSLSocketFactory() { 092 093 return sslSocketFactory; 094 } 095 096 097 @Override 098 public void applyTo(final HTTPRequest httpRequest) { 099 100 if (httpRequest.getMethod() != HTTPRequest.Method.POST) 101 throw new SerializeException("The HTTP request method must be POST"); 102 103 ContentType ct = httpRequest.getContentType(); 104 105 if (ct == null) 106 throw new SerializeException("Missing HTTP Content-Type header"); 107 108 if (ct.match(CommonContentTypes.APPLICATION_JSON)) { 109 110 // Possibly request object POST request, nothing to set 111 112 } else if (ct.match(CommonContentTypes.APPLICATION_URLENCODED)) { 113 114 // Token or similar request 115 Map<String,List<String>> params = httpRequest.getQueryParameters(); 116 params.put("client_id", Collections.singletonList(getClientID().getValue())); 117 String queryString = URLUtils.serializeParameters(params); 118 httpRequest.setQuery(queryString); 119 120 } else { 121 throw new SerializeException("The HTTP Content-Type header must be " + CommonContentTypes.APPLICATION_URLENCODED); 122 } 123 124 // If set for an outgoing request 125 httpRequest.setSSLSocketFactory(sslSocketFactory); 126 } 127}