Giter VIP home page Giter VIP logo

Comments (5)

murraywsmith avatar murraywsmith commented on May 20, 2024 1

I downloaded the latest plugin version and confirmed that the problem is resolved. Thanks!

from servicestack-authentication-identityserver.

wwwlicious avatar wwwlicious commented on May 20, 2024

Hi Murray, thanks for letting us know about your issue.
The short answer is yes, we have a plugin version for IdentityServer4.

The longer answer is that we haven't yet completed the update for the changes in the v1.x release late Dec.
We will look to update the nuget package soon and have already completed some of the work.

In the meantime, if you can supply the error details/stacktrace and any additional information like servicestack and identityserver exact versions that might help us as we update the plugin, that would be appreciated.

from servicestack-authentication-identityserver.

murraywsmith avatar murraywsmith commented on May 20, 2024

Thanks for the quick reply. The information on my system can be found below.

Regarding the upcoming update to the nugget package, I have a few questions:

  • Will the plugin continue to work with ServiceStack 4.0.56 or will I need to upgrade to the latest version of ServiceStack?
  • Do you have a ballpark idea when the updated nugget package will be available? No commitments needed obviously since this is an open source project. I'm just trying to get an idea whether you are thinking it will likely be a week, a month, or longer?

Here's the information on my system:

  • ServiceStack 4.0.56 in my WebApp.

  • IdentityServer is an ASP.NET Core web application using IdentityServer4 1.0.0 (the one released at the end of Dec 2016).

  • My web app is a hello world application. It has one api service (hello) protected by the [Authenticate] attribute. Although once I get [Authenticate] working I will also want to add the [RequiredRole("rolename')] attribute to it as well.

  • When the user navigates to the hello service in the browser, they are redirected to my login page served up by my IdentityServer.

  • during the login, UserAuthProvider.AuthenticateAsync() is called. That results in a call to the IsValidAccessToken(IAuthTokens authTokens) method in IdentityServerAuthProvider. And that eventually results in a call to my IdentityServer's introspection end point.

  • The call to the introspection endpoint ends up making a call to ApiSectretValidator.ValidateAsync(). Inside that call the following lines of code get executed.
    // load API resource
    var api = await _resources.FindApiResourceAsync(parsedSecret.Id);
    if (api == null)
    {
    await RaiseFailureEvent(parsedSecret.Id, "Unknown API resource");

              _logger.LogError("No API resource with that name found. aborting");
              return fail;
          }
    
  • The FindApiResourceAsync() call returns null. When I step through the code in the debugger, I can see that parsedSecret.Id is equal to my ClientId (i.e. it equals "mvc". See my config code for my IdentityServer and the plugin in my WebApp below.). That will always fail to find an api resource because it should be using an api resource name not a client id to find the api resource. So I'm not sure how I got to the point where a client id is being used to search for a resource. (FindApiResourceAsync() is comparing the search value against resource names.) It could be I just don't have things configured correctly?

Here's my configuration on the IdentityServer side:

public class Config
{
    public static IEnumerable<IdentityResource> GetIdentityResources()
    {
        return new List<IdentityResource>
        {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile(),
            new IdentityResource {
                Name = "role",
                UserClaims = new List<string> {
                    JwtClaimTypes.Role 
                    },
            }
        };
    }

    public static IEnumerable<ApiResource> GetApiResources()
    {
        return new List<ApiResource>
        {
            new ApiResource
            {
                Name = "api1",
                UserClaims = new List<string>
                {
                    JwtClaimTypes.Role,
                    JwtClaimTypes.Name
                }
            },
            new ApiResource
            {
                Name = "helloapiresource",
                UserClaims = new List<string>
                {
                    JwtClaimTypes.Role,
                    JwtClaimTypes.Name
                },
                Scopes = new List<Scope>
                {
                    new Scope("helloapiscope", "Scope for Hello api service.")
                }
            }
        };
    }

    public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
        {
            new Client
            {
                ClientId = "mvc",
                ClientName = "MVC Hybrid Client",
                AllowedGrantTypes = GrantTypes.Hybrid,
                RedirectUris = {"http://localhost:5002/signin-oidc", "http://localhost:33952/auth/IdentityServer", "http://localhost:33952/hello" },
                PostLogoutRedirectUris = {"http://localhost:5002" },
                ClientSecrets = new List<Secret>
                {
                    new Secret("secret".Sha256())
                },
                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "role",
                    "helloapiscope"
                },
                RequireConsent = false,
                AlwaysSendClientClaims = true,
                AccessTokenType = AccessTokenType.Jwt,
                AccessTokenLifetime = 120,
                UpdateAccessTokenClaimsOnRefresh = true,
                RefreshTokenUsage = TokenUsage.ReUse,
                RefreshTokenExpiration = TokenExpiration.Sliding,
                SlidingRefreshTokenLifetime = 120,  // 2 minutes
            }
        };
    }

And this is what my configuration for the plugin looks like in AppHost.cs in my WebApp.

public override void Configure(Funq.Container container)
{
SetConfig(new HostConfig
{
WebHostUrl = "http://localhost:33952/"
});

        AppSettings.SetUserAuthProvider()
            .SetAuthRealm("http://localhost:5000")
            .SetClientId("mvc")
            .SetClientSecret("secret")
            .SetScopes("openid profile role helloapiscope");

        Plugins.Add(new IdentityServerAuthFeature());
    }
}

from servicestack-authentication-identityserver.

wwwlicious avatar wwwlicious commented on May 20, 2024

Brillliant! Thank you for that info, really helpful and we will look into the details next week. To answer your first two questions.

  1. Yes we endeavour to remain backwards compatible with major releases of servicestack so unless something in the authprovider contracts has changed, we will remain compatible with v4.0.56.

  2. I appreciate your understanding that we cannot make any promises for the updated package timescales but I think it will be between a week and month. I'm hopeful that it will be next week but I don't want to disappoint anyone

from servicestack-authentication-identityserver.

stuartbfs avatar stuartbfs commented on May 20, 2024

Hi Murray,

We've pushed an updated version of the plugin that might resolve the problem with it looking for the client in the ApiResources.

The ApiResource is new in IdentityServer4 so hadn't been an issue previously but the underlying issue was because the plugin was calling the Introspec endpoint to validate the access token. This is something only ApiResources can do in IdentityServer4.

Can you let me know if you have any further problems?

from servicestack-authentication-identityserver.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.