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