1

I'm trying to create the following structure:

  • WEB API which contains logic (different domain)
  • IdentityServer4 API that provides auth (different domain)
  • Angular 2 Client (different domain)
  • Mobile APP.

Angular 2 client should have Twitter-Sign in button. Below is configuration for Twitter:

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(LogLevel.Debug);

        app.UseCors("CorsPolicy");

        app.UseIdentity();
        app.UseIdentityServer();

        //after identity before mvc
        app.UseTwitterAuthentication(new TwitterOptions
        {
            AuthenticationScheme = "Twitter",
            DisplayName = "Twitter",
            SignInScheme = "Identity.External",
            ConsumerKey = "key",
            ConsumerSecret = "secret",
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            SaveTokens = true,
        });
        app.UseMvc();
    }

This configuration saves my access token and secret provided by twitter in my db.

        bool result = false;
        var info = await signInManager.GetExternalLoginInfoAsync();
        if (info != null)
        {
            var tempUser = info.Principal;
            var claims = tempUser.Claims.ToList();

            var userIdClaim = claims?.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
            var email = claims?.FirstOrDefault(x => x.Type == ClaimTypes.Email);

            if (userIdClaim != null)
            {
                var isRegistered = await IsUserRegistered(info.LoginProvider, info.ProviderKey);
                if (!isRegistered && email != null)
                {
                    var user = new ApplicationUser { UserName = userIdClaim.Value, Email = email.Value };
                    var userCreated = await userManager.CreateAsync(user);
                    isRegistered = userCreated.Succeeded;

                    if (isRegistered)
                    {
                        var addLoginresult = await userManager.AddLoginAsync(user, info);
                        isRegistered = addLoginresult.Succeeded;
                        if (isRegistered)
                        {
                            await signInManager.SignInAsync(user, isPersistent: false);
                        }
                    }
                }

                if (isRegistered)
                {
                    var succeded = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
                    if (succeded.Succeeded)
                    {
                        IdentityResult updateResult = await signInManager.UpdateExternalAuthenticationTokensAsync(info);
                        result = updateResult.Succeeded;



                    }
                }
            }
        }

        if (!result)
        {
            await signInManager.SignOutAsync();
        }

        return Redirect(System.Net.WebUtility.UrlDecode(returnUrl));

What I'm trying to find out is how should I implement my ExternalLoginCallback method to return tokens to Client (Angular or any other) that later will be used to authenticate in WEB API (or multiple APIs). For now I can see Auth cookie in reponse.

3
  • this is all done in the Javascript Client example on the IdentityServer4. You're Javascript client, redirects you to login via IdentityServer4, It returns you an access token which you append in the authorization header in a request to your webapi Commented Mar 24, 2017 at 15:08
  • When I'm sending the access_token from twitter from the client I'm getting the following in log: dentityServer4.AccessTokenValidation.Infrastructure.NopAuthenticationMiddleware:Information: Twitter was not authenticated. Failure message: No token found. Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed for user: (null). Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. Commented Mar 24, 2017 at 15:47
  • @VitalyEvilAvenger Were you able to crack it? Commented Jul 19, 2019 at 4:17

1 Answer 1

2

Check out this Damienbod's great example on configuring IdentityServer4 with webapi and Angular2 (Angular4 already!) https://damienbod.com/2016/03/02/angular2-openid-connect-implicit-flow-with-identityserver4/

Basically there is no difference if you use twitter external login or IdentityServer4 login itself. You can remove Identity server login form and leave only twitter external login link. In short what you should do:

  1. Configure identity server to be able login via twitter at http://youridetityserver/Account/Login

  2. Set login link in your angular app to http://youridetityserver/connect/authorize with proper parameters. You can find parameters list here http://docs.identityserver.io/en/release/endpoints/authorize.html

  3. In angular2 app extract id_token parameter from returnURL

  4. Set Bearer header in calls to your WebApi server from angular2 app

  5. Setup WebApi to use IdentityServer authorization.

Sign up to request clarification or add additional context in comments.

2 Comments

I've seen that example, the main difference, that I'm trying to implement an external login in the system. The problem is that I don't know how to get an access to my API Controller using access_token that was granted me by twitter or how to exchange that twitter access_token to local Id4 server access_token.
A bit late :) You can create custom IExtensionGrantValidator implemetation. See example here. linkedin.com/pulse/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.