OAuth2-OpenIDConnect-JWT-Samples icon indicating copy to clipboard operation
OAuth2-OpenIDConnect-JWT-Samples copied to clipboard

Identity Server is an API Project?

Open AdwardNguyen opened this issue 6 years ago • 4 comments

Hi HamidMosalla In your project, you build identityServer with MVC Project, you can login, logout, redirect error and more. In my example, i build identityServer is an API Project

  1. MVC Core: Login (call API authentication - MVC Client - Port: 5001)
  2. API Authentication (IdentityServer - Port: 5000)
  3. API Core (Secured API - other feature - Port: 5002)

When I start MVC Client (with authorize attribute) it's always call redirecturi from configuration and then call the next url: https://localhost:5000/account/login... but I want redirect to login screen from MVC Core (https://localhost:5001/User/Login)

Please help me!

AdwardNguyen avatar Oct 31 '18 06:10 AdwardNguyen

Sorry for the late response, I think it doesn't matter that your IdentityServer project is an API, you could still serve normal cshtml pages on it, and maybe setting the sign in path for your MVC client to that specific login path that you setup in your IdentityServer authority, that's the general way I'd go about solving this problem.

HamidMosalla avatar Nov 22 '18 04:11 HamidMosalla

Thank you, I found a solution by ClientCredentials for MVC client app I'll check the authorization in this project and custom redirect login It's working fine! Thanks for your comment!

AdwardNguyen avatar Nov 22 '18 04:11 AdwardNguyen

Good news, do you think you can share some code about what you did here?

HamidMosalla avatar Nov 22 '18 04:11 HamidMosalla

Identity Server: API Project

namespace ADS.API.Authentication.Configurations.IdentityServer
{
    public class Config
    {
        // scopes define the resources in your system
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
            };
        }

        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("API.Core", "ADS API Core")
            };
        }
        public static IEnumerable<Client> GetClients(IConfiguration configuration)
        {
            return new List<Client>
    {
        new Client
        {
            ClientId = "Inside",
            ClientName = "ADS Inside",
            AllowedGrantTypes = GrantTypes.ClientCredentials,

            ClientSecrets =
            {
                new Secret(configuration["Client:Inside:Secret"].Sha256())
            },
            //RedirectUris = {configuration["Client:Inside:RedirectUris"].ToString()},
            //PostLogoutRedirectUris = {configuration["Client:Inside:PostLogoutRedirectUris"].ToString() },

            AllowedScopes =
            {
                //IdentityServerConstants.StandardScopes.OpenId,
               //  IdentityServerConstants.StandardScopes.Profile,
                "API.Core"
            },
            AllowOfflineAccess = true
        }
    };
        }
    }
}

MVC Client app

AuthorizationFilter

public void OnAuthorization(AuthorizationFilterContext context)
        {
            if(context.HttpContext.User.Identity.IsAuthenticated)
            {
                var value = context.RouteData.Values["controller"] + "." + context.RouteData.Values["action"];
                var hasClaim = context.HttpContext.User.Claims.Any(c => c.Type == ClaimTypesConstants.Permissions && (c.Value == value || c.Value == ClaimValuesConstants.Permissions));
                if (!hasClaim)
                {
                    context.Result = new ForbidResult();
                }
            }
            else
                context.Result = new RedirectToActionResult("Login", "User", null);
        }

User Controller > Login

var loginInfo = await _apiFactory.PostAsync<UserLoginViewModel, UserInfoViewModel>(model, "Authentication/Login", HostConstants.ApiAuthentication);
                var tokenClient = new TokenClient(Configuration["AuthenticationServer:Authority"] + "connect/token", "Inside", Configuration["Client:Inside:Secret"]);

//Access Token for call API Core or another application
                var tokenResponse = await tokenClient.RequestClientCredentialsAsync(Configuration["AuthenticationServer:ApiName"]);

var claims = new List<Claim>
                {
                    ......
                    new Claim(ClaimTypesConstants.Access_Token, tokenResponse.AccessToken, ClaimValueTypes.String),
                    new Claim(ClaimTypesConstants.Permissions, loginInfo.Permissions, ClaimValueTypes.String)
                };

API.Core Startup.cs

 services.AddAuthorization();
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = Configuration["AuthenticationServer:Authority"];
                    options.RequireHttpsMetadata = false;
                    options.ApiName = Configuration["AuthenticationServer:ApiName"];
                });

AdwardNguyen avatar Nov 22 '18 05:11 AdwardNguyen