keycloak email template use client base url - email

I am trying to use client base url or realm frontend url in requiredActions.ftl and password-reset.ftl. How can I do that? I cant use theme properties as we only have one keycloak instance with different realms as environments and I will use same email theme for these environments but base urls will change across these realms/clients.
My tried ideas:
client.getBaseUrl
session.getContext.getClient.getBaseUrl
these didnt work out. I only want to use this realm/client base url to generate my new password reset link which will use base url and user id.

Related

What is the workflow for a basic Auth OIDC with Keycloak

I have keycloak on docker (v20.0.2) and as you know some versions change some or good part of the UI, so is hard to follow tutorials around the web...
I am trying to follow this particular tuto
https://developers.redhat.com/blog/2020/11/24/authentication-and-authorization-using-the-keycloak-rest-api#keycloak_sso_demo
that seems the more updated. My keycloak is actually behind traeffic and thomseddon/traeffic-fordward-auth with a docker-compose file (but the connection through traeffic is good and I have acces to admin UI)
So on step 10 of the tutorial things change for me, I have to look for that particular view inside:
Click on lateral menu Client Scope
Click on button Create client scope
Give a name to the scope, and click on Tab Mapper
All mappers are predefined... so there is no "New mapper" don't understand this bit
then just follow the tuto
With that series of steps I get an error when retriving the token...
https://keycloak:8443/realms/education/protocol/openid-connect/token
enter image description here
(this are fake local data from the realm I created for testing)
that responds with a or something similar I have also tried to change the grant_type to password, and the same happens can not query the token....
{
"error": "invalid_client",
"error_description": "Invalid client or Invalid client credentials"
}
But if I do not link a user with an scope/role as in the tuto suggest then I get the token, but of course I want to use the role or scope to limit who can see which endpoint and who can not
Any step that I'm missing from this update, do you have the same error?
Thank you in advance
I have tried to run it with different combinations of options to see if there is a toggle that actually allows me to fetch the token
Also with different types of grant_type
I will build an API in Python (I don't know Java and prefer Json instead of XML) that connect to this keycloak to allow users or not based on their scope/role/permission or something
I need to be able to block user so if user Student try to access an url from another Student he get blocked that url. So is based on the role or scope or I don't know which is prefered or easer to accomplish, the mission is to block users or not based on a factor that could be used for this in keycloak.

How to enable 2FA using email using keycloak-admin-client in spring boot

My requirement is enable 2FA using email in Keycloak.
When enabled, if user tries to login through email & password ,after user is successfully authenticated ,time based token will be sent to email .
User will do this action from custom UI i.e in our product we have UI to enable/disable 2FA for user.
We are using Keycloak & we want to achieve this using Keycloak API.
I am using keycloak-admin-client to interact with Keycloak API but I did not find sufficient resources to achieve this using keycloak-admin-client.
I am looking a way using keycloak-admin-client how to enable 2FA for user.
Any help will be highly appreciated.
Thank You
You should add custom REST endpoints to Keycloak to be able to enable 2FA from your custom UI. We have done this before. It's not that much complicated, but it requires you to have a look at Keycloak source to see what it's doing when OTP gets activated. Some important classes to check/use are TotpBean, OTPCredentialModel and OTPPolicy.
In order to enable the 2FA, we needed to show the QR code image in our custom UI. So we added an endpoint to Keycloak that instantiates an instance of TotpBean. It's the one that gives you access to the QR code image and the secret value that are required to generate the equivalent string representation of the image so that it could be scanned/entered in the 2FA app (e.g. Google Authenticator). Here is an example of how such an endpoint would look like:
#GET
#Produces({MediaType.APPLICATION_JSON})
#Path("/o2p-enable-config/{email}")
#NoCache
public Response fetchOtpEnableConfig(#Email #PathParam("email") String email) {
UserModel user = session.users().getUserByEmail(email, realm);
TotpBean totp = new TotpBean(session, realm, user, session.getContext().getUri().getRequestUriBuilder());
return Response
.ok(new YouOTPResponseClass("data:image/png;base64, " + totp.getTotpSecretQrCode(), totp.getTotpSecret(), totp.getTotpSecretEncoded()))
.build();
}
Then on your own backend, you call this endpoint and send the user's email to it and receive the image and the secret value. You can just display the image as is in your UI and keep the secret value on your backend (e.g. in user's session). When user scans the image using the app and enters the totp value provided by the app in your custom UI, you send the totp value and the secret to another endpoint that you should add to the Keycloak. This second endpoint is the one that does that verification of the value and enables 2FA.
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Path("/enable-2fa/{email}")
#NoCache
public Response enable2Fa(#Email #PathParam("email") String email, OtpDetails optDetails) {
OTPPolicy policy = realm.getOTPPolicy();
String totp = optDetails.getTotp();
UserModel user = session.users().getUserByEmail(email, realm);
OTPCredentialModel credential = OTPCredentialModel.createFromPolicy(realm, optDetails.getSecret(), optDetails.getUserLabel());
if (CredentialValidation.validOTP(totp, credential, policy.getLookAheadWindow())) {
CredentialHelper.createOTPCredential(session, realm, user, totp, credential);
return Response.noContent().status(204).build();
} else {
return Response.status(BAD_REQUEST).build();
}
}
Keycloak supports multiple 2FA for each user. That's why it also has a property named label that allows user to name them so that it would be displayed in the 2FA login scenario with given name. You can also allow user to enter the label value in your custom UI and pass it to the second endpoint (or just pass an empty value to Keycloak if you're not going to allow your users to setup multiple 2FA).
I know it seems complicated, but it's actually not that much. The Keycloak domain model is well designed and when you get familiar with it, you can easily find what you need to do and wrap it in custom APIs. But always ensure that exposing a functionality would not compromise the overall security model of the system.
Take a look at keycloak two factor email authenticator provider
https://github.com/mesutpiskin/keycloak-2fa-email-authenticator
I agree that is necessary to write a custom provider for this use case.
Take a look at https://www.n-k.de/2020/12/keycloak-2fa-sms-authentication.html and https://www.youtube.com/watch?v=GQi19817fFk for a look at how to implement that.
That is an example via SMS, but via e-mail would be very similar, changing just the way of sending the code to the user.

How to pass dynamic values to Apigee with key?

I have a rest application that pulls data from database based on the user choice of City or County via UI.
The city, and county are dynamically passed in as the user is able to choose all 50 states.
The endpoints are like this:
http://localhost:8080/my-api/state/FL/City
http://localhost:8080/my-api/state/FL/County
http://localhost:8080/my-api/state/CA/City
http://localhost:8080/my-api/state/AK/County
etc...etc....
Now I want to secure these endpoints using Apigee along with a key. I have created the proxy and product and able to get json from application with my new Apigee URL:
https://company.api-nonprod.com/my-first-api/state/TX/City?apikey=ldekQ5VqlXFQq7YusetSeqbeidxdo5
So far so good. :)
Now I need to add this EndPoint to the front end configuration file.
My local endpoint worked fine.
http://localhost:8080/my-api/state
How do I add this new Apigee Endpoint and key?
This doesn't work as it keeps appending the parameters to the end of url instead of before the apikey.
https://company.api-nonprod.com/my-first-api/state?apikey=ldekQ5VqlXFQq7YusetSeqbeidxdo5
error url
https://company.api-nonprod.com/my-first-api/state?apikey=ldekQ5VqlXFQq7YusetSeqbeidxdo5/TX/City
After going over the Apigee documentation I made my way to the Develop tab in which I can specify how the APIKey can be referenced.
<VerifyAPIKey name="APIKeyVerifier">
<APIKey ref="request.formparam.x-apikey"/>
</VerifyAPIKey>
<VerifyAPIKey name="APIKeyVerifier">
<APIKey ref="request.header.x-apikey"/>
</VerifyAPIKey>
<VerifyAPIKey name="APIKeyVerifier">
<APIKey ref="request.queryparam.x-apikey"/>
</VerifyAPIKey>
Now I'm stuck in AssignMessage message documentation.
How do I pass dynamic values to Apigee with key?
You have to handle constructing URL in your application.
Try to hit from postman.. have your proxy url and your requestMapping appened with your proxy url.
it should work, or it would have worked by this time ;) , since two months gone :P

SharePoint Online: Redirect URIs for multi-site environment

We have a multi-site environment where each site has its own redirect URL. We want to use a single Client ID and Secret for our application but register multiple redirect URIs to it. Is it possible to add multiple URLs in below registration form:
I don't think there is possible solution to add on multiple URLs on the SharePoint online app registration form.
But from what i understand there is another way to achieve use a single Client ID and Secret for application and perform multiple redirects.
You can control the redirect url using the appredirect.aspx by specifying the redirect_uri parameter if you need to redirect from the default one check here for reference.
Basiclly it call the subsite page containing the below JS to install the app.
var url = String.format(
"{0}/_layouts/15/appredirect.aspx?client_id={1}&redirect_uri=https://***.azurewebsites.net/<<controller>>/<<view method containing the code to install the app>>?{{StandardTokens}}",
<<subsite url>>, "<<client id>>");
window.location.href = url;
The above javascript calls the appredirect.aspx page which then calls the app site as below,
https://****.azurewebsites.net/home?SPHostUrl=<<subsiteurl>>&SPLanguage=en-US&SPClientTag=1&SPProductNumber=**&SPAppWebUrl=<<weburl>>
Note: The above can be extended to check for the successful installation of the app and display an error message accordingly.
SPWeb.LoadAndInstallWeb equivalent REST / Javascript CSOM is also available here.
Here are some relevant links:
Use the redirect URL in an add-in that asks for permissions on the fly
Redirect URIs and a sample redirect page

How can I get the url and / or port number of a sails app before it lifts in /config?

I'm building a Sails app. In it, I'm using passport-azure-ad. When setting up passport, I need to tell it where to send the user after they sign in (for example: http://localhost:1337/login/callback), which means I need to tell it the url of the current sails app. But sometimes, the app is on localhost:1337, sometimes it's on localhost:81, sometimes it's on localhost:3000, or if I'm using browser-sync, it's on 10.18.152.135:3000, and in production, it's on https://www.<my-domain>.com.
This passport strategy doesn't allow relative urls either. I need to send it the full absolute callback url.
Use environment-based config files to hard-code different domain URLs