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