As web applications and APIs are an integral part of our digital infrastructure, ensuring their security has never been more important. In a world where data breaches and cyber-attacks are increasingly common, following best practices for securing your applications is essential. The .NET framework provides developers with a powerful set of tools to build secure, robust web applications and APIs. This article explores key security practices in .NET, covering authentication, authorization, identity management, and data encryption, along with practical code examples for each.
Authentication and Authorization
Securing web applications and APIs starts with ensuring that only authenticated and authorized users can access sensitive resources. .NET provides several ways to implement robust authentication and authorization.
JWT Authentication
JSON Web Tokens (JWT) are commonly used to authenticate API requests. JWT allows secure transmission of user information, ensuring that only authenticated users can access specific endpoints.
Example: JWT Configuration This example demonstates how to configure JWT authentication in your Program.csfile.
Authentication Setup: The ConfigureServices method registers the JWT Bearer authentication scheme. It sets the external provider’s URL (Authority), specifies the expected Audience for the token, and defines token validation parameters, such as validating the issuer, audience, and token expiration without any clock skew (time tolerance).
Authorization Setup: The AddAuthorization method configures a policy that requires users to have the “Admin” role to access certain resources.
Controller and Middleware: The AddControllers call registers the controllers, and in the Configure method, UseAuthentication and UseAuthorization are added to the request pipeline to ensure authentication and authorization are enforced. Finally, the application maps controller endpoints using MapControllers.
OAuth2 and OpenID Connect
OAuth2 and OpenID Connect are widely used for managing user authentication and access delegation. These protocols are essential when building applications that require third-party integrations or Single Sign-On (SSO) capabilities.
Configure OAuth2 and OpenID Connect in Program.cs to allow users to authenticate via an external identity provider (e.g., Google, Facebook):
Example: OpenID Connect Configuration This code configures authentication using both cookie-based authentication and OpenID Connect for an ASP.NET Core application.
Authentication Setup: In the ConfigureServices method, authentication schemes are defined:
DefaultAuthenticateScheme and DefaultSignInScheme are set to the cookie-based authentication scheme, meaning cookies will be used to authenticate and store user sessions.
DefaultChallengeScheme is set to OpenID Connect, so when authentication is required, the app will redirect to an OpenID Connect provider for login.
2. OpenID Connect Setup: The OpenID Connect settings specify:
Authority: The URL of the OpenID Connect provider (e.g., an identity provider like Azure AD or Google).
ClientId and ClientSecret: These are credentials the app uses to authenticate with the provider.
ResponseType is set to “code”, meaning the app will use the authorization code flow to authenticate.
SaveTokens is set to true, so the authentication tokens (like the access and refresh tokens) are saved for later use.
Advanced Identity Management with IdentityServer
For more complex authentication and authorization scenarios, IdentityServer or ASP.NET Core Identity is essential. IdentityServer provides a robust framework for managing user authentication and API access, supporting OAuth2, OpenID Connect, and more.
IdentityServer4 Setup for OAuth2 and OpenID Connect
IdentityServer4 is a powerful framework for handling OAuth2 flows, including Client Credentials, Authorization Code, and Implicit Grant types. It allows you to manage client applications and user identities efficiently.
Example: Configure Clients and API Scopes in Identity Server This code defines the configuration for clients and API scopes in an identity server (such as IdentityServer4) to handle OpenID Connect and OAuth 2.0 authentication.
public static class Config { public static IEnumerable<Client> Clients => new Client[] { new Client { ClientId = "client", ClientSecrets = { new Secret("secret".Sha256()) }, AllowedGrantTypes = GrantTypes.Code, RedirectUris = { "https://localhost:5001/signin-oidc" }, PostLogoutRedirectUris = { "https://localhost:5001/signout-callback-oidc" }, AllowedScopes = { "openid", "profile", "api1" } } };
public static IEnumerable<ApiScope> ApiScopes => new ApiScope[] { new ApiScope("api1", "My API") }; }
Clients Configuration: The Clients property returns an array of clients. In this example, there is one client defined.
ClientId: The unique identifier for the client is "client".
ClientSecrets: The client uses a secret (hashed with SHA-256) to authenticate with the identity server.
AllowedGrantTypes: The client is allowed to use the authorization code flow (GrantTypes.Code), a secure flow where the authorization code is exchanged for tokens.
RedirectUris: After authentication, the client is redirected to this URI (https://localhost:5001/signin-oidc).
PostLogoutRedirectUris: After logging out, the user is redirected to this URI (https://localhost:5001/signout-callback-oidc).
AllowedScopes: The client is allowed to request access to the "openid", "profile", and "api1" scopes, which includes the user’s OpenID Connect identity, profile data, and access to an API.
2. API Scopes Configuration:
The ApiScopes property defines available API scopes. In this example:
One API scope is defined with the name "api1" and description "My API". This scope controls access to the API resources that clients can request.
ASP.NET Core Identity
If you need more granular control over user management, ASP.NET Core Identity is the preferred solution for managing users, roles, and claims.
ASP.NET Core Identity can be used alongside IdentityServer for complex scenarios, such as integrating external authentication providers, multi-factor authentication (MFA), and more.
This code configures identity and authorization for an ASP.NET Core application, setting up user authentication and role-based access control.
public void ConfigureServices(IServiceCollection services) { services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders();
Identity Setup: The AddIdentity<ApplicationUser, IdentityRole>() method adds ASP.NET Core Identity services to the application:
ApplicationUser: A custom user class (presumably extending the built-in IdentityUser class) that represents users in the system.
IdentityRole: Represents roles in the system (e.g., Admin, User).
AddEntityFrameworkStores<ApplicationDbContext>(): Configures Identity to use Entity Framework with ApplicationDbContext to store user and role data in a database.
AddDefaultTokenProviders(): Adds default token providers for generating tokens used in password resets, email confirmations, etc.
2. Authorization Setup:
The AddAuthorization method defines a custom authorization policy:
A policy named "AdminOnly" is created, requiring the user to have the "Admin" role to access resources protected by this policy.
Data Encryption in .NET
Encrypting sensitive data is a core part of securing your web applications. In .NET, there are built-in encryption libraries that help secure data in transit and at rest.
Encrypting Data in Transit (HTTPS)
For data in transit, always ensure that your web application uses HTTPS to encrypt communication between the client and server.
Example: Enforcing HTTPS in ASP.NET Core To enforce HTTPS, you can configure your application to redirect all HTTP requests to HTTPS:
For encrypting sensitive data stored in databases or files, AES (Advanced Encryption Standard) is a widely-used and secure encryption algorithm. .NET provides the System.Security.Cryptography namespace to handle encryption.
Example: Configuring AES to encrypt sensitive data In this example, AES is used to encrypt sensitive data. For storing encryption keys, use a secure key management solution like Azure Key Vault to manage keys and secrets.
using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Encoding.UTF8.GetBytes("a very secure key!"); aesAlg.IV = Encoding.UTF8.GetBytes("initialization vct");
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { swEncrypt.Write("sensitive data to encrypt"); } }
byte[] encrypted = msEncrypt.ToArray(); } }
AES Algorithm Creation: The Aes.Create() method creates an instance of the AES encryption algorithm (aesAlg), which will be used for the encryption process.
Key and IV Setup:
aesAlg.Key: The encryption key is set using the bytes of the string "a very secure key!". This key is critical for encrypting and later decrypting the data.
aesAlg.IV: The initialization vector (IV) is set using the bytes of the string "initialization vct". The IV adds randomness to the encryption process, ensuring that identical data encrypted multiple times will yield different outputs.
3. Encryptor Creation:
The CreateEncryptor method creates an encryptor object (ICryptoTransform encryptor) using the provided key and IV.
4. MemoryStream for Encrypted Data:
A MemoryStream (msEncrypt) is created to hold the encrypted data in memory as it is written.
5. CryptoStream for Encryption:
A CryptoStream (csEncrypt) is created that links the memory stream and the encryptor. The CryptoStreamMode.Write mode is used to write encrypted data to the stream.
6. StreamWriter to Write Data:
A StreamWriter (swEncrypt) is created to write the plain text ("sensitive data to encrypt") into the CryptoStream, where it will be encrypted.
7. Encryption Process:
The sensitive data is written through the StreamWriter, encrypted by the CryptoStream, and finally stored in the MemoryStream.
8. Retrieve Encrypted Data:
After the encryption process completes, the encrypted data is retrieved by converting the contents of the MemoryStream to a byte array (msEncrypt.ToArray()).
Conclusion
Security is an ongoing effort that requires attention to detail and the right tools. By implementing robust authentication and authorization mechanisms like JWT, OAuth2, and OpenID Connect, and utilizing powerful frameworks like IdentityServer and ASP.NET Core Identity, you can ensure that your web applications and APIs are secure and accessible only to the right users. Moreover, employing best practices for data encryption — both in transit and at rest — helps protect sensitive data and ensures compliance with industry standards.
Following these .NET security best practices not only makes your applications safer but also builds trust with your users, which is crucial in today’s digital landscape. Always stay up to date with the latest security protocols, tools, and updates to safeguard your applications and users.
{"id":"2","mode":"button","open_style":"in_modal","currency_code":"USD","currency_symbol":"$","currency_type":"decimal","blank_flag_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":500,"top_media_type":"featured_image","featured_image_url":"https:\/\/robhutton.com\/wp-content\/uploads\/Screenshot-2025-02-19-163019-100x74.png","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":false,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Tip Jar","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"robhutton.com","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"robhutton.com","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for being a supporter!","payment_confirmation_title":"robhutton.com","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":"Voluntary nature: Tips are non-refundable and given voluntarily. No goods\/services in exchange: Tipping doesn\u2019t entitle the user to any product, service, or preferential treatment. Payment processing: Mention that payments are processed securely through a third-party provider. No liability: You aren\u2019t responsible for transaction failures, fraud, or technical issues.","terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}
{"id":"4","mode":"text_link","open_style":"in_modal","currency_code":"USD","currency_symbol":"$","currency_type":"decimal","blank_flag_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/robhutton.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":500,"top_media_type":"featured_image","featured_image_url":"https:\/\/robhutton.com\/wp-content\/uploads\/Screenshot-2025-02-19-163019-100x74.png","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":true,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Like my articles? Tips are appreciated.","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for being a supporter!","payment_confirmation_title":"","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":"Voluntary nature: Tips are non-refundable and given voluntarily. No goods\/services in exchange: Tipping doesn\u2019t entitle the user to any product, service, or preferential treatment. Payment processing: Mention that payments are processed securely through a third-party provider. No liability: You aren\u2019t responsible for transaction failures, fraud, or technical issues.","terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}