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