예제 #1
0
        public OpenIDLoginResponse(Binding <JObject> binding)
        {
            if (binding.BindingDirection != this.BindingDirection)
            {
                throw new ArgumentException("Binding has the wrong binding direction for this document");
            }

            var json = binding.GetDocument();

            if (json == null)
            {
                return;
            }

            this.AccessCode = json["code"]?.ToObject <string>();

            this.ID       = json[nameof(JwtOpenIDPayload.JsonTokenID)]?.ToObject <string>();
            this.Issuer   = json[nameof(JwtOpenIDPayload.Issuer)]?.ToObject <string>();
            this.Subject  = json[nameof(JwtOpenIDPayload.Subject)]?.ToObject <string>();
            this.Audience = json[nameof(JwtOpenIDPayload.Audience)]?.ToObject <string>();
            this.UserID   = json[nameof(JwtOpenIDPayload.AAD_ObjectID)]?.ToObject <string>();

            this.UserName = json[nameof(JwtOpenIDPayload.UniqueName)]?.ToObject <string>();
            if (this.UserName == null)
            {
                this.UserName = json[nameof(JwtOpenIDPayload.AAD_UserPrincipalName)]?.ToObject <string>();
            }

            this.Name = json[nameof(JwtOpenIDPayload.AAD_Name)]?.ToObject <string>();
            if (json[nameof(JwtOpenIDPayload.Roles)] != null)
            {
                if (json[nameof(JwtOpenIDPayload.Roles)].Type == JTokenType.Array)
                {
                    this.Roles = json[nameof(JwtOpenIDPayload.Roles)]?.ToObject <string[]>();
                }
                else
                {
                    this.Roles = json[nameof(JwtOpenIDPayload.Roles)]?.ToObject <string>().Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToArray();
                }
            }
            this.Emails = json[nameof(JwtOpenIDPayload.AAD_Emails)]?.ToObject <string[]>();

            this.Nonce        = json[nameof(JwtOpenIDPayload.Nonce)]?.ToObject <string>();
            this.IssuedAtTime = json[nameof(JwtOpenIDPayload.IssuedAtTime)]?.ToObject <long>();
            this.NotBefore    = json[nameof(JwtOpenIDPayload.NotBefore)]?.ToObject <long>();
            this.Expiration   = json[nameof(JwtOpenIDPayload.Expiration)]?.ToObject <long>();

            this.X509Thumbprint = json[nameof(JwtHeader.X509Thumbprint)]?.ToObject <string>();
            this.KeyID          = json[nameof(JwtHeader.KeyID)]?.ToObject <string>();

            this.State = json["state"]?.ToObject <string>();

            this.OtherClaims = OpenIDJwtBinding.GetOtherClaims(json);

            this.Error            = json["error"]?.ToObject <string>();
            this.ErrorDescription = json["error_description"]?.ToObject <string>();
        }
예제 #2
0
        public OpenIDLogoutResponse(Binding <JObject> binding)
        {
            if (binding.BindingDirection != this.BindingDirection)
            {
                throw new ArgumentException("Binding has the wrong binding direction for this document");
            }

            var json = binding.GetDocument();

            if (json == null)
            {
                return;
            }

            this.ServiceProvider = json[OpenIDBinding.ClientFormName]?.ToObject <string>();
            this.State           = json["state"]?.ToObject <string>();

            this.OtherClaims = OpenIDJwtBinding.GetOtherClaims(json);
        }
예제 #3
0
        public async ValueTask <IdentityModel> LoginCallback(IdentityHttpRequest request)
        {
            OpenIDJwtBinding callbackBinding;

            if (OpenIDJwtBinding.IsCodeBinding(request))
            {
                var callbackCodeBinding = OpenIDBinding.GetBindingForRequest(request, BindingDirection.Response);

                var callbackCodeDocument = new OpenIDLoginResponse(callbackCodeBinding);
                if (!String.IsNullOrWhiteSpace(callbackCodeDocument.Error))
                {
                    throw new IdentityProviderException($"{callbackCodeDocument.Error}: {callbackCodeDocument.ErrorDescription}");
                }

                //Get Token--------------------
                var requestTokenDocument = new OpenIDTokenRequest(callbackCodeDocument.AccessCode, this.secret, OpenIDGrantType.authorization_code, redirectUrl);
                var requestTokenBinding  = OpenIDBinding.GetBindingForDocument(requestTokenDocument, BindingType.Form);

                var requestTokenBody = requestTokenBinding.GetContent();
                var requestToken     = WebRequest.Create(tokenUrl);
                requestToken.Method      = "POST";
                requestToken.ContentType = "application/x-www-form-urlencoded";
                var requestTokenBodyBytes = Encoding.UTF8.GetBytes(requestTokenBody);
                requestToken.ContentLength = requestTokenBodyBytes.Length;
                using (var stream = await requestToken.GetRequestStreamAsync())
                {
#if NETSTANDARD2_0 || NET461_OR_GREATER
                    await stream.WriteAsync(requestTokenBodyBytes, 0, requestTokenBodyBytes.Length);
#else
                    await stream.WriteAsync(requestTokenBodyBytes.AsMemory());
#endif
                    await stream.FlushAsync();
                }

                WebResponse responseToken;
                try
                {
                    responseToken = await requestToken.GetResponseAsync();
                }
                catch (WebException ex)
                {
                    if (ex.Response == null)
                    {
                        throw ex;
                    }
                    var responseTokenStream = ex.Response.GetResponseStream();
                    var error = await new StreamReader(responseTokenStream).ReadToEndAsync();
                    ex.Response.Close();
                    ex.Response.Dispose();
                    throw new IdentityProviderException(error);
                }

                //access_code is a JWT
                callbackBinding = OpenIDJwtBinding.GetBindingForResponse(responseToken, BindingDirection.Response);
            }
            else
            {
                callbackBinding = OpenIDJwtBinding.GetBindingForRequest(request, BindingDirection.Response);
            }

            var callbackDocument = new OpenIDLoginResponse(callbackBinding);
            if (!String.IsNullOrWhiteSpace(callbackDocument.Error))
            {
                throw new IdentityProviderException($"{callbackDocument.Error}: {callbackDocument.ErrorDescription}");
            }

            NonceManager.Validate(serviceProvider, callbackDocument.Nonce);

            if (callbackDocument.Audience != serviceProvider)
            {
                throw new IdentityProviderException("OpenID Audience is not valid", $"Received: {serviceProvider}, Expected: {callbackDocument.Audience}");
            }

            var keys = await GetSignaturePublicKeys(this.identityProviderCertUrl);

            var key = keys.FirstOrDefault(x => x.X509Thumbprint == callbackDocument.X509Thumbprint);
            if (key == null)
            {
                key = keys.FirstOrDefault(x => x.KeyID == callbackDocument.KeyID);
            }
            if (key == null)
            {
                throw new IdentityProviderException("Identity Provider OpenID certificate not found from Json Key Url");
            }
            if (key.KeyType != "RSA")
            {
                throw new IdentityProviderException("Identity Provider OpenID only supporting RSA at the moment");
            }

            RSA rsa;
            if (key.X509Certificates == null || key.X509Certificates.Length == 0)
            {
                var rsaParams = new RSAParameters()
                {
                    Modulus  = Base64UrlEncoder.FromBase64String(key.Modulus),
                    Exponent = Base64UrlEncoder.FromBase64String(key.Exponent)
                };
                rsa = RSA.Create();
                rsa.ImportParameters(rsaParams);
            }
            else
            {
                var certString = key.X509Certificates.First();
                var certBytes  = Convert.FromBase64String(certString);
                var cert       = new X509Certificate2(certBytes);
                rsa = cert.GetRSAPublicKey();
            }

            callbackBinding.ValidateSignature(rsa, requiredSignature);
            callbackBinding.ValidateFields();

            var identity = new IdentityModel()
            {
                UserID          = callbackDocument.UserID,
                UserName        = callbackDocument.UserName ?? callbackDocument.Emails?.FirstOrDefault(),
                Name            = callbackDocument.Name,
                Roles           = callbackDocument.Roles,
                ServiceProvider = callbackDocument.Issuer,
                OtherClaims     = callbackDocument.OtherClaims,
                State           = callbackDocument.State,
                AccessToken     = callbackBinding.AccessToken,
            };

            return(identity);
        }