Base solution for your next web application
Open Closed

Social Media Custom Login #7576


User avatar
0
berenice created

Good morning, Would you be able to give an example on how to create a custom external login with the core module using owin.

thanks, Ricardo.


5 Answer(s)
  • User Avatar
    0
    ryancyq created
    Support Team

    Hi, what is your ANZ project version and framework?

    You can follow this document if you are using MVC5

  • User Avatar
    0
    berenice created

    Hi, We are using the ASP.NET Core Angular version. We want to create a custom module for the user to authenticate in an external website: insert username and password through an external identity provider and get a token from the identity provider to validate.

    Thanks, Ricardo Kligman

  • User Avatar
    0
    ryancyq created
    Support Team

    Hi, you can follow the instructions at https://docs.aspnetzero.com/documents/aspnet-core-angular/latest/Features-Angular-Social-Logins

    ANZ supoorts the external providers mentioned in the link above by default.

    if you need to customizethe username and email fields , please refer to https://docs.aspnetzero.com/documents/aspnet-core-angular/latest/Features-Angular-Social-Logins#iexternallogininfomanager-interface

  • User Avatar
    0
    berenice created

    Hi thanks for the response but it still does not solve my doubts. I had many authentication providers on the previous version of your product (ASP.NET MVC 5X & AngularJS 1x). In particular for SAML2 and other. I I see that the WSFederation registers a typeof(WsFederationAuthProviderApi) in the new version, from my understanding the WsFederationAuthProviderApi does what the provider did in the previous version when they were registered in the app start. Is there a way to see the implementation of the WsFederationAuthProviderApi and see how it interacts with the identity provider server. I also wanted to uderstand how to make this type of authentication "active" in such a way that it always tryes to verify the authentication against the identity provider.

    thanks, Ricardo Kligman

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi Ricardo,

    Here is the content of related class:

    using System;
    using System.IdentityModel.Tokens.Jwt;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.IdentityModel.Protocols;
    using Microsoft.IdentityModel.Protocols.WsFederation;
    using Microsoft.IdentityModel.Tokens;
    
    namespace Abp.AspNetZeroCore.Web.Authentication.External.WsFederation
    {
        public class WsFederationAuthProviderApi : ExternalAuthProviderApiBase
        {
            public const string Name = "WsFederation";
    
            public override async Task<ExternalAuthUserInfo> GetUserInfo(string token)
            {
                var issuer = ProviderInfo.AdditionalParams["Authority"];
                if (string.IsNullOrEmpty(issuer))
                {
                    throw new ApplicationException("Authentication:WsFederation:Issuer configuration is required.");
                }
    
                var metadata = ProviderInfo.AdditionalParams["MetaDataAddress"];
                if (string.IsNullOrEmpty(issuer))
                {
                    throw new ApplicationException("Authentication:WsFederation:MetaDataAddress configuration is required.");
                }
    
                var configurationManager = new ConfigurationManager<WsFederationConfiguration>(metadata,
                    new WsFederationConfigurationRetriever(),
                    new HttpDocumentRetriever()
                );
    
                var validatedToken = await ValidateToken(token, issuer, configurationManager);
    
                var fullName = validatedToken.Claims.First(c => c.Type == "name").Value;
                var email = validatedToken.Claims.First(c => c.Type == "email").Value;
                var fullNameParts = fullName.Split(' ');
    
                return new ExternalAuthUserInfo
                {
                    Provider = Name,
                    ProviderKey = validatedToken.Subject,
                    Name = fullNameParts[0],
                    Surname = fullNameParts.Length > 1 ? fullNameParts[1] : fullNameParts[0],
                    EmailAddress = email
                };
            }
    
            private async Task<JwtSecurityToken> ValidateToken(
                string token,
                string issuer,
                IConfigurationManager<WsFederationConfiguration> configurationManager,
                CancellationToken ct = default(CancellationToken))
            {
                if (string.IsNullOrEmpty(token))
                {
                    throw new ArgumentNullException(nameof(token));
                }
    
                if (string.IsNullOrEmpty(issuer))
                {
                    throw new ArgumentNullException(nameof(issuer));
                }
    
                var discoveryDocument = await configurationManager.GetConfigurationAsync(ct);
                var signingKeys = discoveryDocument.SigningKeys;
    
                var validationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = issuer,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKeys = signingKeys,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.FromMinutes(5),
                    ValidateAudience = false
                };
    
                var principal = new JwtSecurityTokenHandler().ValidateToken(token, validationParameters, out var rawValidatedToken);
                //Validate clientId
                if (ProviderInfo.ClientId != principal.Claims.First(c => c.Type == "aud").Value)
                {
                    throw new ApplicationException("ClientId couldn't verified.");
                }
    
                return (JwtSecurityToken)rawValidatedToken;
            }
        }
    }