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; 019 020 021import java.util.Collections; 022import java.util.LinkedHashMap; 023import java.util.List; 024import java.util.Map; 025 026import com.nimbusds.jose.util.Base64URL; 027import com.nimbusds.oauth2.sdk.util.MultivaluedMapUtils; 028import net.jcip.annotations.Immutable; 029 030 031/** 032 * SAML 2.0 bearer grant. Used in access token requests with a SAML 2.0 bearer 033 * assertion. 034 * 035 * <p>Related specifications: 036 * 037 * <ul> 038 * <li>Assertion Framework for OAuth 2.0 Client Authentication and 039 * Authorization Grants (RFC 7521), section 4.1. 040 * <li>SAML 2.0 Profile for OAuth 2.0 Client Authentication and 041 * Authorization Grants (RFC 7522), section-2.1. 042 * </ul> 043 */ 044@Immutable 045public class SAML2BearerGrant extends AssertionGrant { 046 047 048 /** 049 * The grant type. 050 */ 051 public static final GrantType GRANT_TYPE = GrantType.SAML2_BEARER; 052 053 054 /** 055 * Cached {@code unsupported_grant_type} exception. 056 */ 057 private static final ParseException UNSUPPORTED_GRANT_TYPE_EXCEPTION 058 = new ParseException("The \"grant_type\" must be " + GRANT_TYPE, OAuth2Error.UNSUPPORTED_GRANT_TYPE); 059 060 061 /** 062 * The SAML 2.0 assertion. 063 */ 064 private final Base64URL assertion; 065 066 067 /** 068 * Creates a new SAML 2.0 bearer assertion grant. 069 * 070 * @param assertion The SAML 2.0 bearer assertion. Must not be 071 * {@code null}. 072 */ 073 public SAML2BearerGrant(final Base64URL assertion) { 074 075 super(GRANT_TYPE); 076 077 if (assertion == null) 078 throw new IllegalArgumentException("The SAML 2.0 bearer assertion must not be null"); 079 080 this.assertion = assertion; 081 } 082 083 084 /** 085 * Gets the SAML 2.0 bearer assertion. 086 * 087 * @return The SAML 2.0 bearer assertion. 088 */ 089 public Base64URL getSAML2Assertion() { 090 091 return assertion; 092 } 093 094 095 @Override 096 public String getAssertion() { 097 098 return assertion.toString(); 099 } 100 101 102 @Override 103 public Map<String,List<String>> toParameters() { 104 105 Map<String,List<String>> params = new LinkedHashMap<>(); 106 params.put("grant_type", Collections.singletonList(GRANT_TYPE.getValue())); 107 params.put("assertion", Collections.singletonList(assertion.toString())); 108 return params; 109 } 110 111 112 @Override 113 public boolean equals(Object o) { 114 if (this == o) return true; 115 if (o == null || getClass() != o.getClass()) return false; 116 117 SAML2BearerGrant that = (SAML2BearerGrant) o; 118 119 return assertion.equals(that.assertion); 120 121 } 122 123 124 @Override 125 public int hashCode() { 126 return assertion.hashCode(); 127 } 128 129 130 /** 131 * Parses a SAML 2.0 bearer grant from the specified request body 132 * parameters. 133 * 134 * <p>Example: 135 * 136 * <pre> 137 * grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2- 138 * bearer&assertion=PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU 139 * [...omitted for brevity...]aG5TdGF0ZW1lbnQ-PC9Bc3NlcnRpb24- 140 * </pre> 141 * 142 * @param params The parameters. 143 * 144 * @return The SAML 2.0 bearer grant. 145 * 146 * @throws ParseException If parsing failed. 147 */ 148 public static SAML2BearerGrant parse(final Map<String,List<String>> params) 149 throws ParseException { 150 151 // Parse grant type 152 String grantTypeString = MultivaluedMapUtils.getFirstValue(params, "grant_type"); 153 154 if (grantTypeString == null) 155 throw MISSING_GRANT_TYPE_PARAM_EXCEPTION; 156 157 if (! GrantType.parse(grantTypeString).equals(GRANT_TYPE)) 158 throw UNSUPPORTED_GRANT_TYPE_EXCEPTION; 159 160 // Parse JWT assertion 161 String assertionString = MultivaluedMapUtils.getFirstValue(params, "assertion"); 162 163 if (assertionString == null || assertionString.trim().isEmpty()) 164 throw MISSING_ASSERTION_PARAM_EXCEPTION; 165 166 return new SAML2BearerGrant(new Base64URL(assertionString)); 167 } 168}