Unauthorized error with oauth2-proxy´s allow-group flag - kubernetes

I am using oauth2 to handle the authentication/authorization via a company´s SSO provider of a web app running in k8.
The authentication works like a charm, however, once enable authorization for a specific group ( here: "ADMIN"), I always get a 403 - Forbidden "Invalid session: unauthorized" error.
Version:
quay.io/oauth2-proxy/oauth2-proxy:v7.3.0
SSO Provider: oidc
My setup:
extraArgs:
show-debug-on-error: True
oidc-groups-claim: "ent_group"
allowed-group: ["ADMIN"]
oidc-email-claim: "email"
scope: "openid ent_group"
whitelist-domain: ...
cookie-domain: ...
It matches the response from the SSO provider when tested with Postman:
{
"email": "user#mail.com",
"entitlement_group": [
"ADMIN",
"USER"
],
"app_id": "app"
}
What do I do wrong?

Related

MSAL issue in .net 6

I am using MSAL for my authentication, in my React code i am generating jwt token and sending the token in heading to my .net 6 backend code .
my .net code like below
1.I have added [Authorize] on Controller level.
2.In program.cs i have added below code
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
3.In my appsetting.json i have added below code
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "XXXXX",
"ClientId": "XXXXX",
"Scopes": "XXXX"
},
when i am trying to call the endpoint from postman getting 401 unauthorized error.
Bearer error="invalid_token", error_description="The signature is invalid"
Can anyone please help

Register confidential OIDC client through registration endpoint

I would like to programmatically register confidential OIDC client (the client is a backend service). I checked the keycloak document about it. And I use the “Initial access token“ approach as recommended.
After I created a "initial access token" on the UI console, I register a new client by:
POST https://my-keycloak-host/auth/realms/MyRealm/clients-registrations/default
Headers: Authorization: Bearer <initial access token>
{ "clientId": "my-client" }
The response contains a registrationAccessToken. But I expect to get a client secret. How can I get it? And what is the usage for that registrationAccessToken?
For some unknown reason Keycloak doesn't set secret properly. But you can define own secret with secret property in the payload (tested with Keycloak 16.1.1), e.g.:
{
"clientId": "my-client",
"secret": "my-secret"
}
Doc:
https://openid.net/specs/openid-connect-registration-1_0.html
https://www.keycloak.org/docs/latest/securing_apps/index.html#_client_registration

Using OAuth 2 to authenticate to Azure DevOps REST APIs fails with TF400813 (user not authorized)

I am following the documentation posted here (https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops).
I have a react-based webapp and a powershell-based function app, both in Azure. My function app is presently using a personal access token created with my work account (AAD) credentials, which is not desirable. My goal is to use OAuth2 to authorize my function app to make code changes to a GIT repository on behalf of a webapp user. When I follow the instructions above, I am able to acquire what appears to be a valid authorization code, access token, and refresh token, I receive the following error message from Azure DevOps:
TF400813: The user 'ffffffff-ffff-ffff-ffff-ffffffffffff' is not authorized to access this resource.
…
401 - Uh-oh, you do not have access.
The request requires authentication.
4/21/2021 12:04:16 AM (UTC)
ffffffff-ffff-ffff-ffff-ffffffffffff
Sign out and login with different account
I have obscured the guids in the example above, but the user GUID appears to match the GUID I find for my work account when I call the legacy identity APIs (https://learn.microsoft.com/en-us/rest/api/azure/devops/ims/identities/read%20identities?view=azure-devops-rest-6.0).
I created my application (https://app.vsaex.visualstudio.com/app/register) with the same scopes that I used to create my personal access token. I verified in my dev.azure.com profile that my application is listed as an authorized OAuth app, as expected after creating the authorization request and receiving the authorization code.
The error message above is confusing to me. It says that the user (me) is not authorized to access the resource but also says that the authentication failed. Which is it?
Is this a problem with how I am acquiring my authorization/access tokens? Am I somehow using the wrong account? Are my scopes wrong?
Reproduction of Problem
Here is the state from my registered application:
My application state:
{
"scopes": "vso.code_full vso.code_status vso.graph_manage vso.identity_manage vso.threads_full vso.tokens",
"tokenUrl": "https://app.vssps.visualstudio.com/oauth2/token",
"state": "foo",
"authCallback": "https://myapp.azurewebsites.net/oauth-callback",
"clientSecret": "S.S.S-S-S",
"authUrl": "https://app.vssps.visualstudio.com/oauth2/authorize",
"appWebsite": "https://myapp.azurewebsites.net/",
"appSecret": "S",
"appId": "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"
}
Step 1. Authorize the application.
I invoke the following auth URI from an in-private browser.
I authenticate my work account, and authorize the application for the requested scopes.
I can verify the app is an authorized oauth app in my dev.azure.com profile.
https://app.vssps.visualstudio.com/oauth2/authorize?client_id=FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF&response_type=Assertion&state=foo&scope=vso.code_full%20vso.code_status%20vso.graph_manage%20vso.identity_manage%20vso.threads_full%20vso.tokens&redirect_uri=https://myapp.azurewebsites.net/oauth-callback
I receive an authcode, "A.A.A-A-A-A" (shown decoded/obfuscated below):
{
"typ": "JWT",
"alg": "RS256",
"x5t": "....."
}
{
"cid": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"csi": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"nameid": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"iss": "app.vstoken.visualstudio.com",
"aud": "app.vstoken.visualstudio.com",
"nbf": 1618438026,
"exp": 1776204426
}
Step 2. Request the access token and refresh token from my powershell function app:
I make a rest api call to the token endpoint:
"Uri": "https://app.vssps.visualstudio.com/oauth2/token"
"Method": "POST"
"ContentType": "application/x-www-form-urlencoded"
"Body": "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=S.S.S-S-S&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=A.A.A-A-A-A&redirect_uri=https://myapp.azurewebsites.net/oauth-callback"
…and I get the following JSON response:
Token Response:
{
"access_token": "X.X.X-X-X-X-X-X-X",
"token_type": "jwt-bearer"
"expires_in": 3599,
"refresh_token": "R.R.R-R-R-R",
"scope": "vso.code_full vso.code_status vso.graph_manage vso.identity_manage vso.threads_full vso.tokens vso.authorization_grant"
}
Yielding the following JWT for the access token:
{
"typ": "JWT",
"alg": "RS256",
"x5t": "....."
}
{
"nameid": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"scp": "vso.code_full vso.code_status vso.graph_manage vso.identity_manage vso.threads_full vso.tokens",
"aui": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"appid": "ffffffff-ffff-ffff-ffff-ffffffffffff",
"iss": "app.vstoken.visualstudio.com",
"aud": "app.vstoken.visualstudio.com",
"nbf": 1618963456,
"exp": 1618967056
}
Step 3. Make a DevOps REST API call.
In this case, I am requesting a list of respositories in my org/project:
"Uri": "https://dev.azure.com/myorg/myproj/_apis/git/repositories?api-version=6.0"
"Method": "GET"
"Headers": {"Authorization": "Bearer X.X.X-X-X-X-X-X-X"}
This is where things go wrong. DevOps returns a 401 error indicating that my account is not authorized.
TF400813: The user 'ffffffff-ffff-ffff-ffff-ffffffffffff' is not authorized to access this resource.
If I make the exact same http GET from Step 3, but I substitute my PAT with identical scopes as the registered application, the call succeeds. The PAT seems to be created with the exact same profile/account that is authorized in Step 1.
This behavior can be observed when the organization admins have disabled OAuth in the settings. The relevant option can be viewed by any member of the org at e.g. https://dev.azure.com/contoso/_settings/organizationPolicy
Sadly there is no better indication of this for the app or the user, as far as I can see.
Your app can still ask the user for authorization, all OAuth operations succeed, a seemingly valid access token gets returned, but then it simply does not work and returns 401 from all APIs, even if a PAT with the same scope(s) works fine.

Keycloak frontend and backend clients

This is related to keycloak clients. My frontend is connected to public client and backend is connected to confidential client.
I am able to login, get the code, as I am using response_type=code by turning on "Standard Flow Enabled".
This code redirects and returns me Idtoken, refreshtoken and token.
Now I need to communicate with backend which is confidential, I would like to authenticate user using some of the values which I have received from the frontend client.
How can I do that?
Here is my frontend and backend conf
FRONTEND
{
"realm": "xyz",
"auth-server-url": "http://localhost:8333/auth/",
"ssl-required": "external",
"resource": "frontend-app",
"public-client": true,
"confidential-port": 0,
"enable-cors": true
}
BACKEND
keycloak.auth-server-url=http://localhost:8333/auth
keycloak.realm=xyz
keycloak.resource=backend-app
keycloak.principal-attribute=preferred_username
keycloak.bearer-only=true
keycloak.credentials.secret=xxx-xxx-xxx
this is from realm setting
This might help somebody.
My backend service which is springboot project with spring security keycloakAuthenticationProvider does authenticate the token received from the frontend public client.
Call from frontend
axios({
method: 'GET',
url: '/api/authenticate',
headers:{'Authorization': 'Bearer '+keycloak.token+''}
}).then((r) => {
console.log("response",r)
})
Call to backend
#GetMapping("/api/authenticate")
public ResponseEntity<SecureUserDto> authenticate() {
String username = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
User user = userRepository.findWithPrivilegesByUsername(username);
return ResponseEntity.ok();
}
But i still was not able to get it right on postman at ../token end point provided by keycloak server.
Anyways my work is done.

How to test Keycloak's Administration REST API

how can I test the Keycloak native services
The documentation presents several services such as: users management, customers, groups and sessions, I have tried in many ways to test these services and without success. Perhaps due to the incorrect configuration
I saw an example on Stackoverflow that showed the correct path for services
Eg.
http://{address-and-port}/auth/admin/realms/{Realm}/users
And some settings on how to test on the postman, but I did not succeed in invoking
does anyone have an example or can help me how to activate / consume these services.
Thanks!
Services to consume: (Keycloak Admin REST API)
https://www.keycloak.org/docs-api/8.0/rest-api/index.html]
I exported you a Postman Collection: https://pastebin.com/Aaf3BUah you can import it into postman.
But I want to point out, how to use the API:
My example uses a running keycloak instance (8.0.2) on
http://localhost:80
with the user admin and the password Pa55w0rd
In consists of 2 requests:
Login:
Login with my admin user and fetch a access-token used in Request 2.
POST http://localhost:80/auth/realms/master/protocol/openid-connect/token
Content-Type:x-www-form-urlencoded
with the following parameters (change username/password)
username:admin
password:Pa55w0rd
grant_type:password
client_id:admin-cli
As a result i will get some data, but important is the access_Token-Bearer:
{
"access_token": "eyJhbGc...JDjfg", //i reduced the string
...
}
Keep in mind, this token is necessary to execute Request2. But it is only valid for 60 seconds, so be fast while testing :-)
Get all Users:
GET http://localhost:80/auth/admin/realms/master/users
Header Authorization: Bearer eyJhbGc...JDjfg
Response:
[
{
"id": "9fec4b6c-3648-425b-a90f-f6dd78f421ab",
"createdTimestamp": 1581017581626,
"username": "admin",
"enabled": true,
"totp": false,
"emailVerified": false,
"disableableCredentialTypes": [],
"requiredActions": [],
"notBefore": 0,
"access": {
"manageGroupMembership": true,
"view": true,
"mapRoles": true,
"impersonate": true,
"manage": true
}
}
]
With this example, you should be able to access different REST API endpoints. But make sure you include a valid access_token in every request you send - otherwise you will just get Not Authorized response
Here is the full Postman Administration Rest API of keycloak
https://documenter.getpostman.com/view/7294517/SzmfZHnd
It is for keycloak 10 (but work for 11 too - tested)
Open it in postman, adjust environment variables with your keycloak host and params.
You will get a full functionnal keycloak admin rest api.