001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2010 Sun Microsystems, Inc. 015 * Portions copyright 2012-2016 ForgeRock AS. 016 */ 017package org.forgerock.opendj.ldap.controls; 018 019import static com.forgerock.opendj.ldap.CoreMessages.ERR_AUTHZIDRESP_CONTROL_BAD_OID; 020import static com.forgerock.opendj.ldap.CoreMessages.ERR_AUTHZIDRESP_NO_CONTROL_VALUE; 021 022import org.forgerock.i18n.LocalizableMessage; 023import org.forgerock.opendj.ldap.ByteString; 024import org.forgerock.opendj.ldap.DecodeException; 025import org.forgerock.opendj.ldap.DecodeOptions; 026 027import org.forgerock.util.Reject; 028 029/** 030 * The authorization response control as defined in RFC 3829. The authorization 031 * identity control extends the Lightweight Directory Access Protocol (LDAP) 032 * bind operation with a mechanism for requesting and returning the 033 * authorization identity it establishes. 034 * <p> 035 * The authorization identity is specified using an authorization ID, or 036 * {@code authzId}, as defined in RFC 4513 section 5.2.1.8. 037 * <p> 038 * The following excerpt shows how to get the authorization identity established 039 * when binding to the directory server. 040 * 041 * <pre> 042 * Connection connection = ...; 043 * String bindDN = ...; 044 * String bindPassword = ...; 045 * 046 * BindRequest request = 047 * Requests.newSimpleBindRequest(bindDN, bindPassword.toCharArray()) 048 * .addControl(AuthorizationIdentityRequestControl 049 * .newControl(true)); 050 * 051 * BindResult result = connection.bind(request); 052 * AuthorizationIdentityResponseControl control = 053 * result.getControl(AuthorizationIdentityResponseControl.DECODER, 054 * new DecodeOptions()); 055 * // Authorization ID returned: control.getAuthorizationID() 056 * </pre> 057 * 058 * @see AuthorizationIdentityRequestControl 059 * @see org.forgerock.opendj.ldap.requests.WhoAmIExtendedRequest 060 * @see <a href="http://tools.ietf.org/html/rfc3829">RFC 3829 - Lightweight 061 * Directory Access Protocol (LDAP) Authorization Identity Request and 062 * Response Controls </a> 063 * @see <a href="http://tools.ietf.org/html/rfc4532">RFC 4532 - Lightweight 064 * Directory Access Protocol (LDAP) "Who am I?" Operation </a> 065 * @see <a href="http://tools.ietf.org/html/rfc4513#section-5.2.1.8">RFC 4513 - 066 * SASL Authorization Identities (authzId) </a> 067 */ 068public final class AuthorizationIdentityResponseControl implements Control { 069 070 /** The OID for the authorization identity response control. */ 071 public static final String OID = "2.16.840.1.113730.3.4.15"; 072 073 /** 074 * Creates a new authorization identity response control using the provided 075 * authorization ID. 076 * 077 * @param authorizationID 078 * The authorization ID for this control. 079 * @return The new control. 080 * @throws NullPointerException 081 * If {@code authorizationID} was {@code null}. 082 */ 083 public static AuthorizationIdentityResponseControl newControl(final String authorizationID) { 084 return new AuthorizationIdentityResponseControl(false, authorizationID); 085 } 086 087 /** The authorization ID for this control. */ 088 private final String authorizationID; 089 090 private final boolean isCritical; 091 092 /** A decoder which can be used for decoding the authorization identity response control. */ 093 public static final ControlDecoder<AuthorizationIdentityResponseControl> DECODER = 094 new ControlDecoder<AuthorizationIdentityResponseControl>() { 095 096 @Override 097 public AuthorizationIdentityResponseControl decodeControl(final Control control, 098 final DecodeOptions options) throws DecodeException { 099 Reject.ifNull(control); 100 101 if (control instanceof AuthorizationIdentityResponseControl) { 102 return (AuthorizationIdentityResponseControl) control; 103 } 104 105 if (!control.getOID().equals(OID)) { 106 final LocalizableMessage message = 107 ERR_AUTHZIDRESP_CONTROL_BAD_OID.get(control.getOID(), OID); 108 throw DecodeException.error(message); 109 } 110 111 if (!control.hasValue()) { 112 // The response control must always have a value. 113 final LocalizableMessage message = ERR_AUTHZIDRESP_NO_CONTROL_VALUE.get(); 114 throw DecodeException.error(message); 115 } 116 117 final String authID = control.getValue().toString(); 118 return new AuthorizationIdentityResponseControl(control.isCritical(), authID); 119 } 120 121 @Override 122 public String getOID() { 123 return OID; 124 } 125 }; 126 127 /** Prevent direct instantiation. */ 128 private AuthorizationIdentityResponseControl(final boolean isCritical, 129 final String authorizationID) { 130 Reject.ifNull(authorizationID); 131 this.isCritical = isCritical; 132 this.authorizationID = authorizationID; 133 } 134 135 /** 136 * Returns the authorization ID of the user. The authorization ID usually 137 * has the form "dn:" immediately followed by the distinguished name of the 138 * user, or "u:" followed by a user ID string, but other forms are 139 * permitted. 140 * 141 * @return The authorization ID of the user. 142 */ 143 public String getAuthorizationID() { 144 return authorizationID; 145 } 146 147 @Override 148 public String getOID() { 149 return OID; 150 } 151 152 @Override 153 public ByteString getValue() { 154 return ByteString.valueOfUtf8(authorizationID); 155 } 156 157 @Override 158 public boolean hasValue() { 159 return true; 160 } 161 162 @Override 163 public boolean isCritical() { 164 return isCritical; 165 } 166 167 @Override 168 public String toString() { 169 final StringBuilder builder = new StringBuilder(); 170 builder.append("AuthorizationIdentityResponseControl(oid="); 171 builder.append(getOID()); 172 builder.append(", criticality="); 173 builder.append(isCritical()); 174 builder.append(", authzID=\""); 175 builder.append(authorizationID); 176 builder.append("\")"); 177 return builder.toString(); 178 } 179 180}