We are evaluating Keycloak to replace Forgerock for user registration
Our current workflow provides a registration screen. On submitting the registration form, an email is sent to the user to verify their email and activate their account. The link in the email confirms the user registration before creating the user in forgerock.
My questions:
Is there a way to create the user after the email verification as a confirmation?
I have this implementation but sendVerifyEmail it is just for checking the email and basically the user can login even if he/she didn't check the email
Keycloak keycloak = KeycloakBuilder
.builder()
.serverUrl(KEYCLOAK_URL)
.realm(KEYCLOAK_REALM)
.username(KEYCLOAK_USER)
.password(KEYCLOAK_PASSWORD)
.clientId(KEYCLOAK_ADMIN_CLI)
.build();
CredentialRepresentation credential = createPasswordCredentials(userRegistrationRequest.getPassword());
UserRepresentation user = new UserRepresentation();
user.setEmail(userRegistrationRequest.getEmail());
user.setCredentials(Collections.singletonList(credential));
user.setEnabled(true);
// Get realm
RealmResource realmResource = keycloak.realm(KEYCLOAK_REALM);
UsersResource usersResource = realmResource.users();
// Create user (requires manage-users role)
Response response = usersResource.create(user);
String userId = CreatedResponseUtil.getCreatedId(response);
System.out.println("Response: " + response.getStatusInfo());
System.out.println(userId);
UserResource u = realmResource.users().get(userId);
u.sendVerifyEmail();
This is late though but you can set the user representation email verified to false when creating the user. So they won't be able to access until they verify the email.
Related
Getting javax.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized while trying to create new user in keycloak with spring boot service.
In KeycloakConfig class. it is breaking during creating keycloak instance with HTTP 401 Unauthorized. "message": "javax.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized",
Am I missing anything? I dont have any extra role configuration in the keycloak client or realm role.
I was thinking to add ".authorization(...) in KeycloakBuilder.builder but I'm not sure what to specify.
public static Keycloak getInstance(User user) {
if (keycloak == null) {
keycloak = KeycloakBuilder.builder()
.serverUrl("http://localhost:8080/auth")
.realm("myrealm")
.username(user.getUsername()).password(user.getPassword())
.grantType(OAuth2Constants.PASSWORD)
.clientId("myclient")
.clientSecret("0a53569564d2a748a0a5482699")
.resteasyClient(new ResteasyClientBuilder().connectionPoolSize(10).build()).build();
}
return keycloak;
}
In service class
UsersResource usersResource = KeycloakConfig.getInstance(user).realm("myrealm").users();
CredentialRepresentation credentialRepresentation = createPasswordCredentials(user.getPassword());
UserRepresentation kcUser = new UserRepresentation();
kcUser.setUsername(user.getEmail());
kcUser.setCredentials(Collections.singletonList(credentialRepresentation));
kcUser.setFirstName(user.getFirstName());
kcUser.setLastName(user.getLastName());
kcUser.setEmail(user.getEmail());
kcUser.setEnabled(true);
kcUser.setEmailVerified(false);
javax.ws.rs.core.Response response = usersResource.create(kcUser);
System.out.println("kcUser: " + kcUser.toString());
System.out.printf("Repsonse: %s %s%n", response.getStatus(), response.getStatusInfo());
in properties file
keycloak.realm=myrealm
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.resource=myclient
keycloak.credentials.secret=0a5356444d26a748a0a5482699
keycloak.ssl-required= external
keycloak.use-resource-role-mappings= true
keycloak.bearer-only=true
keycloak.principal-attribute=preferred_username
Due to missing imports I assume that KeycloakBuilder is comming from package org.keycloak.admin.client.KeycloakBuilder
Based on your provided code examples you are trying to instantiate a Keycloak instance with an user you just want to create. That user is lack of the privileges to create a new user.
That said you need to create an Keycloak instance with an user that has admin rights / roles. At least "manage-users, view-clients, view-realm, view-users"
keycloak = KeycloakBuilder.builder()
.serverUrl(KEYCLOAK_SERVER_URL)
.realm("master")
.clientId("admin-cli")
.username("admin")
.password("admin")
.build();
With admin access you are able to create users for several realms.
// Create a new user
final UserRepresentation newUser = new UserRepresentation();
newUser.setUsername("username");
newUser.setFirstName("fristname");
newUser.setLastName("lastname");
newUser.setEmail("username#example.com");
newUser.setEnabled(true);
// Now you need to get the realm you want the user to add to and the user ressource
final UserResource realm = keycloak.realm("nameOfTheRealm").users();
// Create the user for the realm
final Response createUserResponse = userRessource.create(newUser);
// check response if everything worked as expected
Make sure the admin account is created under 'myrealm'. You cannot use the default admin account (master realm) to create the user for 'myrealm'
In order for a user to have the right to manipulate and call Keycloak's API, you must set the client role for that user
Step 1: User should create a administrators like "admin" password "abc123" in your client "myrealm"
Step 2: Click admin user after move to Roles mapping tab and assign some necessary permissions to admin user as below
Step 3: Replace password in .username(user.getUsername()).password(user.getPassword()) with "abc123"
Hope to help you!
By default, Strapi has a welcome email template and password reset template. For the custom function we are writing, we want to create users without a password (or random password the user doesn't know). Then, when our function is finished, we want to send the user a welcome email (overwriting/disabling the default), with a password reset link. Therefore, we need to call the function/service to reset the password for the user, and receive the URL to send this in the welcome email.
However, currently I cannot find any information regarding the function/service to reset the user password. The only method I now see is to call http://localhost/auth/reset-password with the username or email, but would like to use a service such as strapi.services.user.resetPassword(userID) to get the URL back.
Does this function exists and/or is this possible?
Using Strapi 3.1.2
I have move my original answer here since it was more relevant to the question.
To reset a user password, we have to provide an identifier which is in this case the username. The possible steps are:
Query the user based on the identifier
Generate new hash password based on provided randomly generated value
Update the user password with the newly generated hash-password.
The implementation at a controller can be like this:
module.exports = {
resetPassword: async ctx => {
....
// Provide identifier and newPassword
const params = ctx.request.body;
const identifier = params.identifier
const newPassword = params.newPassword
// Get User based on identifier
const user = await strapi.query('user', 'users permissions').findOne({username: identifier});
// Generate new hash password
const password = await strapi.plugins['users-permissions'].services.user.hashPassword({password: newPassword});
// Update user password
await strapi
.query('user', 'users-permissions')
.update({ id: user.id }, { resetPasswordToken: null, password });
...
}
}
Don't forget to implement isOwner policy, or if the old password can be provided, we can validate the process using isValidPassword
// Validate given old password against user query result password
const isValidPassword = await strapi.plugins['users-permissions'].services.user.validatePassword(old.password, user.password);
I have the following scenario. If the user doesn't have a valid session cookie, the application A is redirected to another application B. In Application B, I show a login form to the user and after I get their credentials I authenticate the user and redirect the user via Okta back to Application A but I don't see any session cookies. Is there something I'm missing? See below:
Login.aspx.cs
public void authenticate() {
var oktaClient = newOktaClient("my_API_Key", "myportal.oktapreview.com/");
var authClient = oktaClient.GetAuthClient();
var res = authClient.Authenticate(loginCtrl.UserName,loginCtrl.Password);
var uri = string.format("https://myportal.oktapreview.com/login/sessionCookieRedirect?token={0}&redirectUrl=http://localhost/myapp", res.SessionToken);
Response.Redirect(uri);
}
After I redirect with the sessionCookieRedirect, the user is redirected as expected to http://localhost/myapp but when I look in the browser I don't see any session cookie.
I registered an app as a valid admin in my network.
I got my token.
when i request a list of tokens to impersonation I receive only my token and not all the tokens (of users in my network).
This is the request I'am making:
https://www.yammer.com/api/v1/oauth/tokens.json?consumer_key={0}&user_id={1}", CONSUMER_KEY, UserId
Where {0} = My Application Client Id,
Where {1} = My UserId (The verified admin user id).
what could i be doing wrong?
Thanks guys.
I found the answer.
My error was I was registered under
"xxx.com"
and when I requested the token I was under the domain of:
"yyy.com"
so the token I received was not the right token.
Another mistake I made was trying to impersonate verified admins - a verified admin can't impersonate another verified admin.
**
Solution:
Register a new app with a user that is registered on the right domain.
Get the token with thee user that is registered on the right domain.
Get id's of users that are not verified admin.
**
Thanks for all your help.
Hope this info contribute to someone.
You can pass in user_id the sender_id from the post object
var config = require('../config');
module.exports = function (sender_id, tk) {
var params = '?' + 'user_id=' + sender_id + '&consumer_key=' + config.YAMMER_CONSUMER_KEY + '&access_token=' + tk;
var url = 'https://www.yammer.com/api/v1/oauth/tokens.json' + params;
return url;
};
i'd like to know how can get the user name and his password and use it when i set the crmservice connection
CrmDiscoveryService disco = new CrmDiscoveryService();
disco.Url = "https://localhost/MSCRMServices/2007/SPLA/CrmDiscoveryService.asmx";
//Retrieve a list of available organizations from the CrmDiscoveryService Web service.
RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
HERE I WANT TO PUT THE USERNAME AND PASSWORD FROM THE SIGNIN PAGE
// Substitute an appropriate domain, username, and password here.
orgRequest.UserId = domain + "\\" + username;
orgRequest.Password = password;
RetrieveOrganizationsResponse orgResponse = (RetrieveOrganizationsResponse)disco.Execute(orgRequest);
thanks to the helper :)
I'm assuming you're talking about the IFD signin page? There is no way for you to pull the user's credentials from that page. If you need the user's credentials you'll need to pull them in on a custom page.
You can also accomplish the orgrequest using the UseDefaultCredentials property which will use the current user's credentials:
CrmDiscoveryService disco = new CrmDiscoveryService();
disco.Url = "https://localhost/MSCRMServices/2007/SPLA/CrmDiscoveryService.asmx";
disco.UseDefaultCredentials = true;
Or you can use an HttpContext/HttpRequest auth if you're doing this on a custom page.