001package com.nimbusds.oauth2.sdk; 002 003 004import java.util.LinkedHashMap; 005import java.util.Map; 006 007import com.nimbusds.jose.util.Base64URL; 008import net.jcip.annotations.Immutable; 009 010 011/** 012 * SAML 2.0 bearer grant. Used in access token requests with a SAML 2.0 bearer 013 * assertion. 014 * 015 * <p>Related specifications: 016 * 017 * <ul> 018 * <li>Assertion Framework for OAuth 2.0 Client Authentication and 019 * Authorization Grants (RFC 7521), section 4.1. 020 * <li>SAML 2.0 Profile for OAuth 2.0 Client Authentication and 021 * Authorization Grants (RFC 7522), section-2.1. 022 * </ul> 023 */ 024@Immutable 025public class SAML2BearerGrant extends AssertionGrant { 026 027 028 /** 029 * The grant type. 030 */ 031 public static final GrantType GRANT_TYPE = GrantType.SAML2_BEARER; 032 033 034 /** 035 * The SAML 2.0 assertion. 036 */ 037 private final Base64URL assertion; 038 039 040 /** 041 * Creates a new SAML 2.0 bearer assertion grant. 042 * 043 * @param assertion The SAML 2.0 bearer assertion. Must not be 044 * {@code null}. 045 */ 046 public SAML2BearerGrant(final Base64URL assertion) { 047 048 super(GRANT_TYPE); 049 050 if (assertion == null) 051 throw new IllegalArgumentException("The SAML 2.0 bearer assertion must not be null"); 052 053 this.assertion = assertion; 054 } 055 056 057 /** 058 * Gets the SAML 2.0 bearer assertion. 059 * 060 * @return The SAML 2.0 bearer assertion. 061 */ 062 public Base64URL getSAML2Assertion() { 063 064 return assertion; 065 } 066 067 068 @Override 069 public String getAssertion() { 070 071 return assertion.toString(); 072 } 073 074 075 @Override 076 public Map<String,String> toParameters() { 077 078 Map<String,String> params = new LinkedHashMap<>(); 079 params.put("grant_type", GRANT_TYPE.getValue()); 080 params.put("assertion", assertion.toString()); 081 return params; 082 } 083 084 085 /** 086 * Parses a SAML 2.0 bearer grant from the specified parameters. 087 * 088 * <p>Example: 089 * 090 * <pre> 091 * grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2- 092 * bearer&assertion=PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU 093 * [...omitted for brevity...]aG5TdGF0ZW1lbnQ-PC9Bc3NlcnRpb24- 094 * </pre> 095 * 096 * @param params The parameters. 097 * 098 * @return The SAML 2.0 bearer grant. 099 * 100 * @throws ParseException If parsing failed. 101 */ 102 public static SAML2BearerGrant parse(final Map<String,String> params) 103 throws ParseException { 104 105 // Parse grant type 106 String grantTypeString = params.get("grant_type"); 107 108 if (grantTypeString == null) 109 throw new ParseException("Missing \"grant_type\" parameter", OAuth2Error.INVALID_REQUEST); 110 111 if (! GrantType.parse(grantTypeString).equals(GRANT_TYPE)) 112 throw new ParseException("The \"grant_type\" must be " + GRANT_TYPE, OAuth2Error.UNSUPPORTED_GRANT_TYPE); 113 114 // Parse JWT assertion 115 String assertionString = params.get("assertion"); 116 117 if (assertionString == null || assertionString.trim().isEmpty()) 118 throw new ParseException("Missing or empty \"assertion\" parameter", OAuth2Error.INVALID_REQUEST); 119 120 return new SAML2BearerGrant(new Base64URL(assertionString)); 121 } 122}