In order to have repeatable deployments of keycloak I'm trying to use the import feature to create clients in keycloak. I have noticed that when I import a client, as opposed to the realm, the 'Authorization Enabled' flag is not set to true even if I have set it to true in the JSON that I'm importing. If I try to set it to true after importing I get an error unless I first turn off 'Service Accounts Enabled' and then attempt to enable 'Authorization Enabled'.
The JSON that I'm sending is provided below:
{
"clientId" : "hello-world-authz-service",
"secret" : "secret",
"authorizationServicesEnabled" : True,
"enabled" : True,
"redirectUris" : [ "http://localhost:8080/hello-world-authz-service/*" ],
"baseUrl": "http://localhost:8080/hello-world-authz-service",
"adminUrl": "http://localhost:8080/hello-world-authz-service",
"directAccessGrantsEnabled" : True
}
The JSON above is actually based upon one of the examples that was provided in the keycloak source code and it works when I import everything as a realm, but not when I use just the client portion.
Can anyone provide guidance in regards to how I can import JSON into Keycloak in order to setup a specific client?
I'm using Keycloak 2.5.0.Final Community.
It looks like this issue might have been resolved by this pull request:
https://github.com/keycloak/keycloak/commit/0b5b27ea3a9d68a26e9cd592a1b087ea7478a07c
I can see in the pull request that the code references the authorizationServicesEnabled field.
Related
I successfully configured Wildfly 26 to authenticate via Keycloak following the usual tutorial. Example: https://www.youtube.com/watch?v=2gQO4_7Z5CI
It works as announced - when required the user's browser gets redirected to keycloak, after login it redirects back. That much for authentication. I also checked that the authorization can be performed by running request.isUserInRole(...) which is true if and only if in keycloak some role was associated to that user. That much for authorization.
But the methods request.getRemoteUser() and request.getUserPrincipal().getName() only return the keycloak's userid, which looks like 896128e8-3260-42c8-9457-3c8ee236eb4d.
How can I make Wildfly OIDC to report the username by looking at the preferred_username token claim?
So I learned that Wildfly's OIDC client can be configured to read the principal name from another token claim. For this it was sufficient to add the line
"principal-attribute": "preferred_username",
into my web application's WEB-INF/oidc.json. This is the only line required on top of the configuration generated by Keycloak:
{
"principal-attribute": "preferred_username",
"realm" : "myrealm",
"auth-server-url" : "http://localhost:8180/",
"ssl-required" : "external",
"resource" : "webapp",
"credentials" : {
"secret" : "7BqGXjt7cw6p88DNoiXCi1663bIzKPwY"
},
"confidential-port" : 0
}
When authenticating, the tokens emitted by Keycloak are exactly the same however the client uses the specified field's value instead of the sub value.
From the documentation:
principal-attribute
OpenID Connect ID Token attribute to populate the UserPrincipal name with. If token attribute is null, defaults to sub. Possible values are sub, preferred_username, email, name, nickname, given_name, family_name.
keycloak js version -> ^10.0.2
angular -> ^7.2.16
keycloak.json
{
"realm": "REALM",
"auth-server-url": "<auth-url>/auth/",
"ssl-required": "external",
"resource": "CLIENT_ID",
"verify-token-audience": true,
"credentials": {
"secret": "CLIENT_SECRET_KEY"
},
"use-resource-role-mappings": true,
"confidential-port": 0,
"policy-enforcer": {}
}
using in init like this
const keycloakAuth = Keycloak('keycloak.json');
keycloakAuth.init({ onLoad: 'login-required', checkLoginIframe: false })
when keycloak made this call <auth-url>/auth/realms/guavus/protocol/openid-connect/token than giving this error.
{"error":"unauthorized_client","error_description":"Client secret not provided in request"}
as per documentation removed credential support from javascript adapter
than what is the alternative of this and how to fix this error?
If this is an Angular Single Page Application (SPA), you should be using a public client (which will not use a client secret) per the Keycloak docs:
"One important thing to note about using client-side applications is that the client has to be a public client as there is no secure way to store client credentials in a client-side application."
https://www.keycloak.org/docs/latest/securing_apps/#_javascript_adapter
Yes, I got to know that they removed credential support from javascript adapter
https://www.keycloak.org/docs/latest/release_notes/#credentials-support-removed-from-the-javascript-adapter
https://github.com/keycloak/keycloak/commit/913056b2b2d39707347a39dddb7bdad69fe47cc3
and for javascript adapter they mentioned in document
To use the JavaScript adapter you must first create a client for your application in the Keycloak Administration Console. Make sure public is selected for Access Type.
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.
I'm looking for help of somebody who knows something about Jira add-ons.
I'm trying to implement Jira add-on with an ability to create issues on behalf of a user.
So, I completed all steps (as I think) leading me to my goal, but I faced a problem with impersonating. When I try to create an issue using Jira REST API, I receive the following error:
{
"error": "Add-on 'com.example.myapp' disallowed to impersonate the user because 'no valid active user exists'"
}
What was done:
Folowing the getting started tutorial I created the add-on descriptor:
{
"name": "Hello World",
"description": "Atlassian Connect app",
"key": "com.example.myapp",
"baseUrl": "https://url.ngrok.io",
"vendor": {
"name": "Example, Inc.",
"url": "http://example.com"
},
"authentication": {
"type": "jwt"
},
"scopes": [
"act_as_user",
"read",
"write",
],
"lifecycle": {
"installed": "/api/created",
},
"apiVersion": 1
}
I also implemented webhook to handle 'installed' callback from add-on like described here. So, when a user installs the add-on the webhook will receive the following object:
{
'key': 'com.example.myapp',
'clientKey': '<client key>',
'oauthClientId': '<OAuth client ID>',
'publicKey': '<public key>',
'sharedSecret': '<shared secret>',
'serverVersion': '100095',
'pluginsVersion': '1.250.0',
'baseUrl': 'https://<user's domain>.atlassian.net',
'productType': 'jira',
'description': 'Description',
'eventType': 'installed'
}
Using this data I generated JWT signed with the shared secret like described in the tutorial. So, my JWT payload includes the following claims:
{
'iss': 'urn:atlassian:connect:clientid:<OAuth client ID>',
'sub': 'urn:atlassian:connect:useraccountid:<client key>',
'tnt': 'https://<user's domain>.atlassian.net',
'iss': '<created at>',
'exp': '<created at + 1 minute>'
}
The next step I performed is access token generation using auth.atlassian.io/oauth2/token endpoint and the following parameters:
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<my JWT>&scope=ACT_AS_USER READ WRITE
The result of all these actions is an access token witch I can use to perform REST API requests. But the error described above returned every time I try to create Jira issue performing POST [user's domain].atlassian.net/rest/api/2/issue/ with Authorization: Bearer [access_token] header.
What I've noticed is that account ID in installed callback object (clientKey) has 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' (uuid) format. But when I open my account in Jira (account in witch the add-on is installed) I see that the account ID in URL has 'YYYYYY:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' format. I prepended the subject in my JWT payload with YYYYYY part:
'sub': 'urn:atlassian:connect:useraccountid:'YYYYYY:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
and generated a new access token using this JWT. I've used new access token to create an issue and it was successfully created, the reporter of the issue is a user installed my add-on, just like I wished.
Finally, the question is: where can I find that YYYYYY part for my add-on? How to get it automatically? What I've missed following the tutorials? Any help will be appreciated.
Thank you!
I am trying to get successfully integrate Spring security rest plugin
But I am constantly failed,I am using the memcahed for token storage. Config.groovy Setup which I used to implement the plugin is :
//login end point url
grails.plugin.springsecurity.rest.login.active=true
grails.plugin.springsecurity.rest.login.endpointUrl='/api/login'
grails.plugin.springsecurity.rest.login.failureStatusCode='401'
//for memcached
grails.plugin.springsecurity.rest.token.storage.useMemcached=false
grails.plugin.springsecurity.rest.token.storage.memcached.hosts='localhost:11211'
grails.plugin.springsecurity.rest.token.storage.memcached.username=''
grails.plugin.springsecurity.rest.token.storage.memcached.password=''
grails.plugin.springsecurity.rest.token.storage.memcached.expiration=3600
//token generation
grails.plugin.springsecurity.rest.token.generation.useSecureRandom=true
grails.plugin.springsecurity.rest.token.generation.useUUID=false
I making a request on /api/login via Post man rest client with
{
"username": "john.doe",
"password": "dontTellAnybody"
}
json data but it gives me spring security auth page's html in response, Am I doing some wrong configuration?Is there any futher configuration is required.I mentioned that I am using memcache for token storage.Any Idea will be helpfull for me.
Edit: please see the logs file
Edit2 : please check this log file