The Federation Service could not authorize token issuance for caller 'DOMAIN\Account' - single-sign-on

I am using ADFS in Windows Server 2012 with SAML 2.0 to implement SSO for an MVC application. I started to get this error which I am unable to find a way to solve. What am I doing wrong?
The Federation Service could not authorize token issuance for caller 'xxx\xxxx
'. The caller is not authorized to request a token for the relying party 'https://example.com/SampleMvcApplication/AuthServices'. Please see event 501 with the same instance id for caller identity.
Additional Data
Instance id: xyz
Relying party: https://example.com/SampleMvcApplication/AuthServices
Exception details:
Microsoft.IdentityServer.Service.IssuancePipeline.CallerAuthorizationException: MSIS5007: The caller authorization failed for caller identity System.Security.Claims.ClaimsIdentity for relying party trust https://example.com/SampleMvcApplication/AuthServices.
at System.IdentityModel.AsyncResult.End(IAsyncResult result)
at System.IdentityModel.TypedAsyncResult`1.End(IAsyncResult result)
at System.IdentityModel.SecurityTokenService.EndIssue(IAsyncResult result)
at Microsoft.IdentityServer.Service.SamlProtocol.SamlProtocolService.Issue(IssueRequest issueRequest)
at Microsoft.IdentityServer.Service.SamlProtocol.SamlProtocolService.ProcessRequest(Message requestMessage)
User Action
Use the AD FS Management snap-in to ensure that the caller is authorized to request a token for the relying party.

In the Relying Party Trust (RPT) for this service provider (SP), take a look at the Issuance Authorization Rules tab. You'll need at least one rule to issue the claim type http://schemas.microsoft.com/authorization/claims/permit with a value of true and no claims issuing the claim type http://schemas.microsoft.com/authorization/claims/deny with a value of true, though technically I don't believe any value is needed for either. If all users are allowed to the front door of your SP, you can use the rule template under Add Rule called Permit All Users.

You need to permit that user for the relying party configured in ADFS.
ADFS management -> Relying party Trusts -> Right click your relying party -> Edit claim rules -> Issuance Authorization Rules -> Add Rule -> Permit access to all users.

Related

Disable Keycloak user quickly when account is disabled on identity provider

When an user account is disabled on a connected IdP, how do I ensure the account is blocked as soon as possible on Keycloak? At the moment, the “disabled” user is able to continue using my SPA because Keycloak continues to refresh the access token without speaking to the external IdP.
One of the critical features required by my partners when using SSO is that they have control over their users’ access to my application. At the moment if the user was logged into my SPA, they can continue using it for about 24 hours. I would hope to cut that time down to 5 minutes, the lifetime of the access token.
The external IdP is Google. I have tried using both Keycloak’s builtin Social provider for Google as well as setting up a SAML app in Google and user-defind SAML provider in Keycloak. I’m using Keycloak v9 but can upgrade if necessary.
Is there a recipe to achieve my goal? What options do I need to set in the Keycloak client and SAML provider?
Many thanks!
The approach could be as follows. The resource server will need to do the checking with the IDP, not Keycloak.
Enable the option to Store Tokens and Read Stored Tokens in the IDP settings.
Assign users the broker/read-tokens role.
On the resource server, decide on a frequency to check whether the user has been disabled on the IDP. Be aware of each IDP's token introspection's endpoint. Each time the API is consumed:
First of course verify the access token as usual.
If it's time to verify against the IDP, call the Keycloak API with the access token to retrieve the IDP's access token.
The Keycloak endpoint is: https://{domain}/realms/{realm}/broker/{idpid}/token
Call the IDP's token introspection endpoint to validate the IDP access token.
Act accordingly if the IDP responds that the token is not valid. Respond with 401 and ensure that the Keycloak access token can't be used again. Maybe the end_session_endpoint or revocation_endpoint, not sure.
Token validation endpoints:
Google: https://www.googleapis.com/oauth2/v3/tokeninfo?access_token={access_token}
AuthO: https://{tenant}.eu.auth0.com/userinfo
MS Azure: doesn't exist, good luck with that!

Keycloak authentication: how can a external user get an token without exposing client secret

I have a query about how keycloak is supposed to be working with client without GUI access.
Basically I have:
A keycloak server configured with a realm, clients(Access type confidential) and Users
A server application with a GUI that also provide API, secure with keycloak (client, user, blablabla)
This is kind of working already as I am able to log on the GUI, have the redirect, etc..
Even accessing the APIs works well, when I have access to a GUI: I log on my UI, follow the redirect and get my UI to display the token. The the human (to differentiate the user from an application), can use the token in any API client.
In this context the user never sees the client secret, which is instinctively the right way. (note that I am very opened to people telling me my instinct is wrong!)
What I am NOT able to do so far is to find the way a server application (without GUI) can get a valid token?
The authorization_endpoint, as far as I understand it, requires both the client id and the client secret) to get a token, which I would rather avoid: I don't think giving my client secret to all my "customers" is the proper way to do it.
Alternatively I could create an API on my client that woudl ask for user credential and ask for the token in its behalf, but that would expose the clients credentials to my application, which is against the whole concept!
I tried setting my client Access type as public, but when I use the API call below I also get a error:
POST /auth/realms/realmname/protocol/openid-connect/tokenAPI
'grant_type=client_credentials'
'client_id=client_id'
'username=username'
'password=password'
{
"error": "unauthorized_client",
"error_description": "Public client not allowed to retrieve service account"
}
Would anyone know how this is supposed to be done ?
Thanks in advance.
Max
(...) A server application (without GUI) can get a valid token... typically using the Client Credentials flow.
But we would define in this case a dedicated Client for your server (client?) application to authenticate against. The returned token (not bound to a specific user) will serve for authorizations on allowed applications (i.e. your classic GUI or API clients).
So, basically you should (in very short):
define a specific confidential Client in your Keycloak
add the desired applications (or other Clients) to the Client Scope(s). Those you want to authorize transitively from this Client.
authenticate against this Client with Client Credentials flow (given the token endpoint, client id, credentials, scope)
ensure that you are authenticating through TLS and that parameters are included in request body (and not in headers - for enhanced privacy)
further harden security of your Client(s)
When you do not want anymore this particular server (client?) application to access your applications, you can change the corresponding "authentication" Client's secret/credentials or simply delete it.
"I don't think giving my client secret to all my "customers" is the proper way to do it."
You are right and the proposed method above strictly avoids that. Each customer would have its own credentials.
EDIT
(adding more details)
By performing as above, you would end up with the following scheme:
Flow Keycloak Server
C/S app. or Customer X <--- Client Creds ---> Auth. Client X
--- Access Token ---> Appl. Client <--> Appl. Server
C/S app. or Customer Y <--- Client Creds ---> Auth. Client Y
--- Access Token ---> Appl. Client <--> Appl. Server
Browser users <--- Standard ------> Appl. Client <--> Appl. Server
Note: this is not a detailed flow chart. Arrows mostly show relationships here.
Finally, please note that the terminology may differ a little here, but the proposed method is basically the same that Google uses. So you may aswell take some inpiration from there:
https://developers.google.com/identity/protocols/oauth2
I just had the same problem some weeks ago
In my case, I have a backend API and a frontend application that the users can use.
Eventually, I can't share the client_secret to the frontend application.
So here is my solution:
On keycloak, create a client (ex front_end_client) with grant type public
This client is going to be used by the frontend application to authenticate users using implicit flow (with PKCE will be more secure)
On keycloak, create a second client (On the same REALM as the first client) with grant type confidential, this client is going to be used by the backend API
Now, this is how it works:
Frontend app authenticate users and get the access token (Using the font_end_client)
The frontend app sends this token for every request to the backend
Backend app verify this token, and can retrieve permissions from it

Kubernetes authentication method to use for calling the K8 apis?

i am quite new to kubernetes and I am looking towards certificate based authentication and token based authentication for calling K8 apis. To my understanding, I feel token based approach (openID + OAuth2) is better since id_token will get refreshed by refresh_token at a certain interval and it also works well with the login point(web browser) which is not the case with Certificate based approach . Any more thoughts to this ? I am working using minikube with kubernetes . Can anyone share their thoughts here ?
Prefer OpenID Connect or X509 Client Certificate-based authentication strategies over the others when authenticating users
X509 client certs: decent authentication strategy, but you'd have to address renewing and redistributing client certs on a regular basis
Static Tokens: avoid them due to their non-ephemeral nature
Bootstrap Tokens: same as static tokens above
Basic Authentication: avoid them due to credentials being transmitted over the network in cleartext
Service Account Tokens: should not be used for end-users trying to interact with Kubernetes clusters, but they are the preferred authentication strategy for applications & workloads running on Kubernetes
OpenID Connect (OIDC) Tokens: best authentication strategy for end users as OIDC integrates with your identity provider (e.g. AD, AWS IAM, GCP IAM ...etc)
I advice you to use OpenID Connect. OpenID Connect is based on OAuth 2.0. It is designed with more of an authentication focus in mind however. The explicit purpose of OIDC is to generate what is known as an id-token. The normal process of generating these tokens is much the same as it is in OAuth 2.0.
OIDC brings a step closer to providing with a user-friendly login experience and also to allow us to start restricting their access using RBAC.
Take also look on Dex which acts as a middleman in the authentication chain. It becomes the Identify Provider and issuer of ID tokens for Kubernetes but does not itself have any sense of identity. Instead, it allows you to configure an upstream Identity Provider to provide the users’ identity.
As well as any OIDC provider, Dex supports sourcing user information from GitHub, GitLab, SAML, LDAP and Microsoft. Its provider plugins greatly increase the potential for integrating with your existing user management system.
Another advantage that Dex brings is the ability to control the issuance of ID tokens, specifying the lifetime for example. It also makes it possible force your organization to re-authenticate. With Dex, you can easily revoke all tokens but there is no way to revoke a single token.
Dex also handles refresh tokens for users. When a user logs in to Dex they may be granted an id-token and a refresh token. Programs such as kubectl can use these refresh tokens to re-authenticate the user when the id-token expires. Since these tokens are issued by Dex, this allows you to stop a particular user refreshing by revoking their refresh token. This is really useful in the case of a lost laptop or phone.
Furthermore, by having a central authentication system such as Dex, you need only configure the upstream provider once.
An advantage of this setup is that if any user wants to add a new service to the SSO system, they only need to open a PR to Dex configuration. This setup also provides users with a one-button “revoke access” in the upstream identity provider to revoke their access from all of our internal services. Again this comes in very useful in the event of a security breach or lost laptop.
More information you can find here: kubernetes-single-sign-one-less-identity/, kubernetes-security-best-practices.

Validate oAuth 2 access token in APIGEE without VerifyOAuthTokens policy

We are using Apigee as our Authorization Server (AS) and we have a few Spring Restful services deployed in IBM Bluemix public cloud which acts as our Resource server (RS).
Each of the services has an equivalent proxy service configured in Apigee. For the proxy services, we have configured the VerifyOAuthTokens policy to verify the token passed by the user and return an error if invalid token is passed
The problem is, since our RS is in the public cloud (no plans or need of moving to a dedicated or private cloud) the api endpoints are open and can be invoked by anyone who knows the url.Though the expectation is everyone should call the apis via APIGEE proxies but we cannot force that since we are in public cloud and there are no options of opening ports coming from apigee or something. We would like to take the following approach to secure the api endpoints.
Accept the Authorization header for each call
Take the token and call a validate token service in Apigee
For 2, We are not able to find an APIGEE api which can validate an access token similar to say googles
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=1/fFBGRNJru1FQd44AzqT3Zg
or Github's
GET /applications/:client_id/tokens/:access_token
Is there actually an external APIGEE service to validate a token?
If not, what would be the best way to make sure that only valid users with valid tokens can access the apis?
Thanks,
Tatha
Did you look at this post in the Apigee Community: Using third-party OAuth tokens
We did something similar to this but not using oauth tokens. We used Apigee to do a callout to a third party IDP (identity provider). The 3rd party IDP wasn't able to generate tokens but exposed a web service to authenticate the user. If the user was authenticated successfully (based on interpreting the result received back from the target endpoint webservice), then you tell Apigee that it was successful by setting the external authorization status to true (step #2 in the link).
NOTE: this has to be done inside an Assign Message Policy step PRIOR to the GenerateAccess token operation. Apigee interprets this as a successful authorization and then can generate a valid oauth token that the caller can then send along to access the protected API.

Enterprise Single Sign On

Am searching for Desktop application manage Enterprise
Single Sign On
(SAML v2, Identity Provider , Service Provider )
Here is how i achieved in my enterprise:
There could be 2 approaches
Use "windows authentication" which can give you actual user trying to access website. Any enterprise application ( assuming it being hosted on Intranet) has integration to Active Directory. This User identity can be authenticated using LDAP server
Use OAuth way and use Third party which provide Identity management. Front End calls their services to generate token. This token can be sent to backend which will authenticate this token against the validator service.
I have used ADFS 2.0 as RSTS for SSO where in we have all the IdentityProviders and the Relying parties are configured. You can use the active end point of the STS (in case you want to authenticate against external sources like web api/ web service/ AD/ Database then prefer writing you own custom STS as the IDP).
Firstly you will get the boot strap token from the IDP and then get the Relying party token from the RSTS. In both the calls you need to communicate against the active end point (a wcf end point which implements WS Trust protocol).
Passive end points/ passive calls are used for thin clients.
You can try using ADFS 3.0 which even supports JOT (JSON) tokens (a very light weight token) along with SAML 2.0.