예제 #1
0
		public void Sign(EncodableResponse response) {
			Association assoc;
			string assoc_handle = response.PreferredAssociationHandle;

			if (!string.IsNullOrEmpty(assoc_handle)) {
				assoc = GetAssociation(assoc_handle, AssociationRelyingPartyType.Smart);

				if (assoc == null) {
					Logger.WarnFormat("No associaton found with assoc_handle {0}. Setting invalidate_handle and creating new Association.", assoc_handle);

					response.Fields[response.Protocol.openidnp.invalidate_handle] = assoc_handle;
					assoc = CreateAssociation(AssociationRelyingPartyType.Dumb, null);
				}
			} else {
				assoc = this.CreateAssociation(AssociationRelyingPartyType.Dumb, null);
				Logger.Debug("No assoc_handle supplied. Creating new association.");
			}

			response.Fields[response.Protocol.openidnp.assoc_handle] = assoc.Handle;
			response.Signed.Add(response.Protocol.openidnp.assoc_handle);

			response.Fields[response.Protocol.openidnp.signed] = String.Join(",", response.Signed.ToArray());
			response.Fields[response.Protocol.openidnp.sig] =
				Convert.ToBase64String(assoc.Sign(response.Fields, response.Signed, string.Empty));
		}
예제 #2
0
        public void Sign(EncodableResponse response)
        {
            Association assoc;
            string      assoc_handle = response.PreferredAssociationHandle;

            if (!string.IsNullOrEmpty(assoc_handle))
            {
                assoc = GetAssociation(assoc_handle, AssociationRelyingPartyType.Smart);

                if (assoc == null)
                {
                    Logger.WarnFormat("No associaton found with assoc_handle {0}. Setting invalidate_handle and creating new Association.", assoc_handle);

                    response.Fields[response.Protocol.openidnp.invalidate_handle] = assoc_handle;
                    assoc = CreateAssociation(AssociationRelyingPartyType.Dumb, null);
                }
            }
            else
            {
                assoc = this.CreateAssociation(AssociationRelyingPartyType.Dumb, null);
                Logger.Debug("No assoc_handle supplied. Creating new association.");
            }

            response.Fields[response.Protocol.openidnp.assoc_handle] = assoc.Handle;
            response.Signed.Add(response.Protocol.openidnp.assoc_handle);

            response.Fields[response.Protocol.openidnp.signed] = String.Join(",", response.Signed.ToArray());
            response.Fields[response.Protocol.openidnp.sig]    =
                Convert.ToBase64String(assoc.Sign(response.Fields, response.Signed, string.Empty));
        }
예제 #3
0
        /// <summary>
        /// Respond to this request.
        /// </summary>
        internal EncodableResponse Answer()
        {
            EncodableResponse response = EncodableResponse.PrepareDirectMessage(Protocol);

            bool validSignature = Provider.Signatory.Verify(AssociationHandle, signature, signedFields, signedKeyOrder);

            response.Fields[Protocol.openidnp.is_valid] = validSignature ?
                                                          Protocol.Args.IsValid.True : Protocol.Args.IsValid.False;

            // By invalidating our dumb association, we make it impossible to
            // verify the same authentication again, making a response_nonce check
            // to protect against replay attacks unnecessary.
            Provider.Signatory.Invalidate(AssociationHandle, AssociationRelyingPartyType.Dumb);

            // The RP may be asking for confirmation that an association should
            // be invalidated.  If so, double-check and send a reply in our response.
            string invalidate_handle = Util.GetOptionalArg(Query, Protocol.openid.invalidate_handle);

            if (invalidate_handle != null)
            {
                Association assoc = Provider.Signatory.GetAssociation(invalidate_handle, AssociationRelyingPartyType.Smart);

                if (assoc == null)
                {
                    Logger.Warn("No matching association found. Returning invalidate_handle. ");
                    response.Fields[Protocol.openidnp.invalidate_handle] = invalidate_handle;
                }
            }

            return(response);
        }
예제 #4
0
        public static EncodableResponse CreateAssertion(CheckIdRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }
            if (!request.IsAuthenticated.HasValue)
            {
                throw new InvalidOperationException();
            }
            EncodableResponse response = EncodableResponse.PrepareIndirectMessage(
                request.Protocol, request.ReturnTo, request.AssociationHandle);

            if (request.IsAuthenticated.Value)
            {
                AssertionMessage.CreatePositiveAssertion(response, request.Provider,
                                                         request.LocalIdentifier, request.ClaimedIdentifier);
                Logger.InfoFormat("Created positive assertion for {0}.", request.ClaimedIdentifier);
            }
            else
            {
                AssertionMessage.CreateNegativeAssertion(response, request);
                Logger.InfoFormat("Created negative assertion for {0}.", request.ClaimedIdentifier);
            }
            return(response);
        }
예제 #5
0
        public static void CreatePositiveAssertion(EncodableResponse message,
                                                   OpenIdProvider provider, Identifier localIdentifier, Identifier claimedIdentifier)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            Protocol protocol = message.Protocol;

            message.Fields[protocol.openidnp.mode]     = protocol.Args.Mode.id_res;
            message.Fields[protocol.openidnp.identity] = localIdentifier;
            // We use OriginalString for the return_to to help protect against interop
            // problems with RPs that require an explicit port, or who knows what else.
            message.Fields[protocol.openidnp.return_to] = message.RedirectUrl.OriginalString;
            message.Signed.AddRange(new[] {
                protocol.openidnp.return_to,
                protocol.openidnp.identity,
            });
            if (protocol.Version.Major >= 2)
            {
                message.Fields[protocol.openidnp.claimed_id]     = claimedIdentifier;
                message.Fields[protocol.openidnp.op_endpoint]    = provider.Endpoint.AbsoluteUri;
                message.Fields[protocol.openidnp.response_nonce] = new Nonce().Code;
                message.Signed.AddRange(new[] {
                    protocol.openidnp.claimed_id,
                    protocol.openidnp.op_endpoint,
                    protocol.openidnp.response_nonce,
                });
            }

            Debug.Assert(!message.Signed.Contains(protocol.openidnp.mode), "openid.mode must not be signed because it changes in check_authentication requests.");
            // The assoc_handle, signed, sig and invalidate_handle fields are added
            // as appropriate by the Signatory.Sign method.
        }
예제 #6
0
        public static void CreateNegativeAssertion(EncodableResponse message, CheckIdRequest request)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            Protocol protocol = message.Protocol;

            if (request.Immediate)
            {
                if (protocol.Version.Major >= 2)
                {
                    message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.setup_needed;
                }
                else
                {
                    message.Fields[protocol.openidnp.mode]           = protocol.Args.Mode.id_res;
                    message.Fields[protocol.openidnp.user_setup_url] = request.SetupUrl.AbsoluteUri;
                }
            }
            else
            {
                message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.cancel;
            }
        }
예제 #7
0
        /// <summary>
        /// Creates a message that can be sent to a user agent to redirect them to a
        /// relying party web site complete with authentication information to
        /// automatically log them into that web site.
        /// </summary>
        public static IResponse CreateUnsolicitedAssertion(OpenIdProvider provider,
                                                           Realm relyingParty, Identifier claimedIdentifier, Identifier localIdentifier)
        {
            if (relyingParty == null)
            {
                throw new ArgumentNullException("relyingParty");
            }
            if (claimedIdentifier == null)
            {
                throw new ArgumentNullException("claimedIdentifier");
            }
            if (localIdentifier == null)
            {
                throw new ArgumentNullException("localIdentifier");
            }

            var discoveredEndpoints = new List <RelyingPartyReceivingEndpoint>(relyingParty.Discover(true));

            if (discoveredEndpoints.Count == 0)
            {
                throw new OpenIdException(
                          string.Format(CultureInfo.CurrentCulture, Strings.NoRelyingPartyEndpointDiscovered,
                                        relyingParty.NoWildcardUri));
            }
            var selectedEndpoint = discoveredEndpoints[0];

            EncodableResponse message = EncodableResponse.PrepareIndirectMessage(
                selectedEndpoint.Protocol, selectedEndpoint.RelyingPartyEndpoint, null);

            CreatePositiveAssertion(message, provider, localIdentifier, claimedIdentifier);
            return(provider.Encoder.Encode(message));
        }
예제 #8
0
        public static void CreatePositiveAssertion(EncodableResponse message,
            OpenIdProvider provider, Identifier localIdentifier, Identifier claimedIdentifier)
        {
            if (message == null) throw new ArgumentNullException("message");
            Protocol protocol = message.Protocol;

            message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.id_res;
            message.Fields[protocol.openidnp.identity] = localIdentifier;
            // We use OriginalString for the return_to to help protect against interop
            // problems with RPs that require an explicit port, or who knows what else.
            message.Fields[protocol.openidnp.return_to] = message.RedirectUrl.OriginalString;
            message.Signed.AddRange(new[]{
                    protocol.openidnp.return_to,
                    protocol.openidnp.identity,
                });
            if (protocol.Version.Major >= 2) {
                message.Fields[protocol.openidnp.claimed_id] = claimedIdentifier;
                message.Fields[protocol.openidnp.op_endpoint] = provider.Endpoint.AbsoluteUri;
                message.Fields[protocol.openidnp.response_nonce] = new Nonce().Code;
                message.Signed.AddRange(new[]{
                        protocol.openidnp.claimed_id,
                        protocol.openidnp.op_endpoint,
                        protocol.openidnp.response_nonce,
                    });
            }

            Debug.Assert(!message.Signed.Contains(protocol.openidnp.mode), "openid.mode must not be signed because it changes in check_authentication requests.");
            // The assoc_handle, signed, sig and invalidate_handle fields are added
            // as appropriate by the Signatory.Sign method.
        }
예제 #9
0
        public static EncodableResponse PrepareIndirectMessage(Protocol protocol, Uri baseRedirectUrl, string preferredAssociationHandle)
        {
            EncodableResponse response = new EncodableResponse(protocol, baseRedirectUrl, preferredAssociationHandle);

            if (protocol.QueryDeclaredNamespaceVersion != null)
            {
                response.Fields.Add(protocol.openidnp.ns, protocol.QueryDeclaredNamespaceVersion);
            }
            return(response);
        }
예제 #10
0
        public static EncodableResponse PrepareDirectMessage(Protocol protocol)
        {
            EncodableResponse response = new EncodableResponse(protocol);

            if (protocol.QueryDeclaredNamespaceVersion != null)
            {
                response.Fields.Add(protocol.openidnp.ns, protocol.QueryDeclaredNamespaceVersion);
            }
            return(response);
        }
예제 #11
0
        public static void CreateNegativeAssertion(EncodableResponse message, CheckIdRequest request)
        {
            if (message == null) throw new ArgumentNullException("message");
            if (request == null) throw new ArgumentNullException("request");

            Protocol protocol = message.Protocol;
            if (request.Immediate) {
                if (protocol.Version.Major >= 2) {
                    message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.setup_needed;
                } else {
                    message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.id_res;
                    message.Fields[protocol.openidnp.user_setup_url] = request.SetupUrl.AbsoluteUri;
                }
            } else {
                message.Fields[protocol.openidnp.mode] = protocol.Args.Mode.cancel;
            }
        }
예제 #12
0
        public EncodableResponse Answer()
        {
            Association       assoc    = Provider.Signatory.CreateAssociation(AssociationRelyingPartyType.Smart, Provider);
            EncodableResponse response = EncodableResponse.PrepareDirectMessage(Protocol);

            response.Fields[Protocol.openidnp.expires_in]   = assoc.SecondsTillExpiration.ToString(CultureInfo.InvariantCulture);
            response.Fields[Protocol.openidnp.assoc_type]   = assoc.GetAssociationType(Protocol);
            response.Fields[Protocol.openidnp.assoc_handle] = assoc.Handle;
            response.Fields[Protocol.openidnp.session_type] = session.SessionType;

            IDictionary <string, string> nvc = session.Answer(assoc.SecretKey);

            foreach (var pair in nvc)
            {
                response.Fields[pair.Key] = nvc[pair.Key];
            }

            Logger.InfoFormat("Association {0} created.", assoc.Handle);

            return(response);
        }
예제 #13
0
 public static EncodableResponse PrepareDirectMessage(Protocol protocol)
 {
     EncodableResponse response = new EncodableResponse(protocol);
     if (protocol.QueryDeclaredNamespaceVersion != null)
         response.Fields.Add(protocol.openidnp.ns, protocol.QueryDeclaredNamespaceVersion);
     return response;
 }
예제 #14
0
 public static EncodableResponse PrepareIndirectMessage(Protocol protocol, Uri baseRedirectUrl, string preferredAssociationHandle)
 {
     EncodableResponse response = new EncodableResponse(protocol, baseRedirectUrl, preferredAssociationHandle);
     if (protocol.QueryDeclaredNamespaceVersion != null)
         response.Fields.Add(protocol.openidnp.ns, protocol.QueryDeclaredNamespaceVersion);
     return response;
 }