Authentication with ServiceStack and more provider - authentication

I state that I use ServiceStack to authenticate my services.
My problem is the following I am developing two authentication methods via credentials and via API key.
The implementation is correct but I would like some services to be authenticated through Credentials while other services through API key. Reading from documentation it seemed to me that I understood that it was enough to insert in the [Authenticate] attribute the provider parameter equal to the property Name of the reference Auth class (Credentials or API), getting [Authenticated ("apikey")] for example.
Unfortunately, implementing the example above, if I authenticate with credentials, I can call the service while I would only like this service to be called via API key.
Do you have any solutions?
thanks a lot

The [Authenticate(provider)] will check if the User is considered to be authenticated according to that Auth Provider where it calls the AuthProviders IsAuthorized() to verify if the session is authenticated.
If you want to mandate that a Request was authenticated using an API Key you can check for it in your Service implementation, e.g:
if (Request.GetSession().AuthProvider != ApiKeyAuthProvider.Name)
throw HttpError.Forbidden("Must authenticate with API Key");

Related

ASP.NET Core Authentication via Google Sign In with REST API in between

I have a requirement to authenticate ASP.NET Core App via Google Sign In, but a Web API between client app (i.e. ASP.NET Core app) and Google sign in... I know it sounds confusing, so let me explain it with diagrams.
Here is the typical way to include google sign-in button and get user authenticated via their google credentials, It works perfectly fine
Step 1: First, create a new app on google identity developer portal, generate ClientId, ClientSecret and specify redirect_url like : https://yoursite.com/signin-google.
Step 2: In the Startup.cs class of ASP.NET Core project, Use AddGoogle as authentication middleware and it works perfectly fine.
Including diagram below for your understanding:
And here is the proposed flow. With a REST API in between client and google sign in. Question is, how do I authenticate client ?
From what I understand, you want your Client Application to invoke the REST Service on behalf of the user. The REST service needs assurance that both the Client and the User are authenticated.
We have achieved this using the OpenID Connect Hybrid flow. The bad news is that we had to add another service to the solution to achieve this.
How this differs from your proposed solution is this:
You must have your own identity service, and this must know of the existence of the REST service, the Client Application, and the User Identity.
The Client Application redirects the user to authenticate with the Identity Service (which further on redirects the user to authenticate with Google)
Identity Server provides the client application with an ID token for the user, and also a code which can be exchange for an Access Token
The client application requests the Access Token. This Access Token will authenticate both the client and the user
The client application then authenticates using this access token when invoking the REST Service
The REST Service issues a one-off request to Identity Server for the signature keys, and uses these keys to validate the access token.
We happened to use IdentityServer4 when implementing the Identity Server, but the protocol exists independently of any one implementation.

identityserver4 protect public api

I am using identity server 4, I followed the tutorial, so I have an api, mvc client, console client, and js client.
I saw this blog too, which is probably close to what I need:
https://medium.com/all-technology-feeds/testing-your-asp-net-core-webapi-secured-with-identityserver4-in-postman-97eee976aa16
what I need is an api, where clients can access data, but first, they need authenticate.
we also have the console client, which is also close to what I need.
The only issue with this examples is that in both cases client knows the secret. But in our case multiple clients should use the same api, and if they all have the same secret, they can log in on behalf of each other, but I don't want to have different secrets.
So what I think I could do is to create an api which takes username and password, and returns the token. But I am not sure if this is the right way to do things? This feels like a resource owner flow, which is not supposed to be used for client facing APIs if I am correct. But in that case, how should I go it?
thanks
It seems that there is some confusion. Allow me to give a short summary. First the terminology:
A user is a human that is using a registered client to access resources.
A client is a piece of software that requests tokens from IdentityServer - either for authenticating a user (requesting an identity token) or for accessing a resource (requesting an access token). A client must be first registered with IdentityServer before it can request tokens.
Resources are something you want to protect with IdentityServer - either identity data of your users, or APIs.
Client credentials: The simplest grant type and is used for server to server communication - tokens are always requested on behalf of a client, not a user.
Now about authentication. The client requests tokens at the IdentityServer endpoint. When you use a client in combination with the client credentials flow, then you'll need a clientid + secret. Where secret is really secret and should be known to the client only. You can't use the same secret here. Seems logical when compared to users, they don't share the same password either.
This is close to the resource owner flow, however a client cannot login as a user. For that you'll need another flow, like the hybrid flow. In that case the client logs in on behalf of the user. The difference is the presence of the "sub" claim (the id of the user) in the token.
The client in this case is your app: console or mvc. The first only supports client credentials where the secret is mandatory, the second supports a hybrid flow, where secret may be omitted:
In certain situations, clients need to authenticate with
identityserver, e.g.
confidential applications (aka clients) requesting tokens at the token endpoint
APIs validating reference tokens at the introspection endpoint
The Api is your resource, that you want to protect. The Api never authenticates a user or client. This is done by IdentityServer. It only verifies the token (using the IdentityServer4.AccessTokenValidation package). For that it has its own secret that should only be known to the Api.
In order to grant the client access to the resource you'll need to add the scope to the client in the configuration of IdentityServer. The client is then allowed, not required, to request a token that grants access to the resource.
Again, the Api has nothing to do with authentication. It is also not bound to one client. Multiple clients can access the resource. All you have to do is add the scope to each client that should have access to the resource.
So there is really nothing against it that clients and resources know their secret. You don't have to change anything. All you have to do is choose the appropriate flow.

JWT handling with WSO2-AM

we plan to introduce an API management solution and we're currently setting up a proof of concept with WSO2 AM. We want to use the WSO2 API gateway to check whether a certain consumer application is allowed to use an API and to throttle the request rate.
I work on the identity workflow and I wonder how a consuming application can pass a JWT token to the backend service with WSO2-AM in between.
First, this is our current scenario:
Without API gateway
The consuming application gets a JWT token for its carbon user from an identity provider. The JWT contains some claims about the user, e.g. the roles he/she belongs to.
The app calls the service an passes the JWT token in the Authorization HTTP header like: Authorization: Bearer
The service validates the issuer and signature of the JWT and retrieves the claims from it.
So, this is pretty straight forward. Now we put an API gateway in between the application and the service:
With API gateway
The consuming application gets a JWT token for its carbon user from an identity provider.
The consuming application uses OAuth2 to get an access token for the following API calls. We can use the client_credentials grant type and simply pass the the client id and client secret. I haven't yet tried it, but we could possibly use the JWT grant type (see https://docs.wso2.com/display/ISCONNECTORS/Configuring+JWT+Grant+Type) and use the JWT for passing user information to the API gateway.
The API gateway validates the JWT against the public key of the identity provider when using the JWT grant type.
An access token is returned to the app.
The app sends an API request to the gateway and passes the access token in the Authorization HTTP header.
The gateway validates the access token.
The gateway forwards the API request to the service.
And there is my problem: How can the JWT from 1/2. be passed to the service?
There is a documentation for "Passing Enduser Attributes to the Backend Using JWT" (see https://docs.wso2.com/display/AM210/Passing+Enduser+Attributes+to+the+Backend+Using+JWT), but this would introduce a new JWT, issued and signed by WSO2-AM, and I'm not sure, whether this JWT contains all information from the JWT used to create the access token (or even the original JWT).
Another way I could think of is using a custom HTTP header for passing the JWT through the gateway to the service. I cannot use the Authorization header (as we do without the API gateway), because WSO2-AM expects the access token in that header.
Since I'm not happy with either solutions, I want to ask the experts: How would you solve this?
Thanks,
Torsten
The only possibility I can think of is to send the JWT token in a custom Header for the backend service.

Authentication with WSO2 API Manager

We have a system with three layer includes API Server (Backend), Client Web Site, and End User. Now, the Authentication occurs on API Server, which be done in two case. In one case, Client Web Site call API directly using a token (Client Token) which get from a service based on user/pass and in another case, besides End User login into API Server using Client Web Site, but authentication occurred on API Server other than Client Web Site. Client Site get another token which named as Auth Token (for end user calling), then call API that End User requested by sending two mentioned tokens. By using Client and Auth Tokens, API Server checks whether client and end User are logged in respectively or not. Entities and their relations are illustrated in here
I want to use API Manager as a gateway between API Server and Client Site and manage authentication process with it.
How can I implement this scenario using WSO2 API Manger?
thanks for your response!
Extending the previous answer..
If the backend is behind the API manager (adviced), the API maanger can pass the client/user/application information to the backend as JWT token. So indeed, that's a good use case to use the API Manager
Edit: extending answer based on comments
in one scenario when a user login to client website, it pass the user
& pass to API server. therefore, API server checks the validity of U&P
Indeed, using the default OAuth (code or password profile) will work.
and creates a Auth token as well creates a session for user.
Almost good. A token is returned, there's no user session in API Manager. All authorization is based on the token provided.
of session, that whether Client web site and end user
are logged in or not. the checking process performed by two tokens
Nope. The APIM doesn't check for any session. It checks only the OAuth (Bearer) token.
and in another scenario client web site call API directly without any
request from end user.in this scenario auth token is not exist
The web site (lets call it Application) can authenticate using its own credentials (so called client_credentials profile). It may receive its own OAuth application token.
The same feature is supported in APIM. You can simply get rid of authentication login from your backend (or replace with a simple one) and use APIM Authentication.
APIM uses OAuth2. To cater your requirement, you can use different grant types. For client website, you can use client credentials grant type, and for end users, you can use other grant types such as password or authorization code.
For more details read:
https://docs.wso2.com/display/AM210/Quick+Start+Guide
https://docs.wso2.com/display/AM210/Token+API

OAuth resource owner password flow and HMAC

I have a web api application which implements the Resource Owner Password flow from OAuth specification. Everything works correctly.
Actually I configure everything in my WebApiConfig class by using an Authentication filter like this
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add( new HostAuthenticationFilter( OAuthDefaults.AuthenticationType ) );
As some of my customer asked for a different method of authentication I am evaluating to add a couple of features to my services but stil did not have clear how those features can work together.
In particular I cam across a link which explain in very easy words how to implement a HMAC authentication in web api.
Can I implement this authentication method and let the client to choose which one he want to use? Do they can cohesist together?
Yes, your web api service can send back multiple schemes in the WWW-Authenticate challenge. In your case it can send back 'bearer' and 'hmac' for example.
See also this question for more info on using multiple schemes.
BTW, it's not your web api service that supports Resource Owner Password flow. The client uses this flow to get a token from the authorization server that it can use in a bearer scheme with your service (resource server). HTH.