I'm having an issue where everything works such as roles, and authentication. However, my development has come to a halt because I cannot get the permissions for an account. Permissions always return null and I don't know why.
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
defaultSecurityManager.setAuthenticator(authenticator);
ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
authorizer.setPermissionResolver(new WildcardPermissionResolver());
defaultSecurityManager.setAuthorizer(authorizer);
JdbcRealm realm = new JdbcRealm();
realm.setDataSource(DatabaseUtil.DATA_SOURCE);
realm.setAuthenticationQuery("SELECT password FROM account WHERE username = ?");
realm.setUserRolesQuery("SELECT accountRole FROM account WHERE username = ?");
realm.setPermissionsQuery("SELECT permissions FROM account WHERE username = ?");
realm.setPermissionsLookupEnabled(true);
realm.setCredentialsMatcher(new PasswordMatcher());
defaultSecurityManager.setRealm(realm);
SecurityUtils.setSecurityManager(defaultSecurityManager);
Related
We've migrated from adal4j to msal4j in our java web applications.
All works well but the big difference is that when the user is already logged (maybe in other applications but same browser session) we always see the "select user" page and the user is not logged automatically and redirected to redirect uri as before with adal4j.
This is how we redirect to autentication page:
private static void redirectToAuthorizationEndpoint(IdentityContextAdapter contextAdapter) throws IOException {
final IdentityContextData context = contextAdapter.getContext();
final String state = UUID.randomUUID().toString();
final String nonce = UUID.randomUUID().toString();
context.setStateAndNonce(state, nonce);
contextAdapter.setContext(context);
final ConfidentialClientApplication client = getConfidentialClientInstance();
AuthorizationRequestUrlParameters parameters = AuthorizationRequestUrlParameters
.builder(props.getProperty("aad.redirectURI"), Collections.singleton(props.getProperty("aad.scopes"))).responseMode(ResponseMode.QUERY)
.prompt(Prompt.SELECT_ACCOUNT).state(state).nonce(nonce).build();
final String authorizeUrl = client.getAuthorizationRequestUrl(parameters).toString();
contextAdapter.redirectUser(authorizeUrl);
}
I've tried to remove .prompt(Prompt.SELECT_ACCOUNT)
but I receive an error
Any ideas?
• You might be getting the option for selecting the user account after switching to MSAL4J in your browser even after the SSO is enabled because either clearing the token cache is enabled in your code or MsalInteractionRequiredException option is thrown and specified accordingly due to which the application asks for a token interactively.
Thus, please check which accounts information is stored in the cache as below: -
ConfidentialClientApplication pca = new ConfidentialClientApplication.Builder(
labResponse.getAppId()).
authority(TestConstants.ORGANIZATIONS_AUTHORITY).
build();
Set<IAccount> accounts = pca.getAccounts().join(); ’
Then, from the above information, if you want to remove the accounts whose prompts you don’t want to see during the user account selection such that the default account should get selected and signed in automatically, execute the below code by modifying the required information: -
Set<IAccount> accounts = pca.getAccounts().join();
IAccount accountToBeRemoved = accounts.stream().filter(
x -> x.username().equalsIgnoreCase(
UPN_OF_USER_TO_BE_REMOVED)).findFirst().orElse(null);
pca.removeAccount(accountToBeRemoved).join();
• And for the MsalInteractiveRequiredException class in the code, kindly refer to the below official documentation link for the AcquireTokenSilently and other reasons responsible for the behaviour. Also, refer to the sample code given below for your reference regarding the same: -
https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-error-handling-java#msalinteractionrequiredexception
IAuthenticationResult result;
try {
ConfidentialClientApplication application =
ConfidentialClientApplication
.builder("clientId")
.b2cAuthority("authority")
.build();
SilentParameters parameters = SilentParameters
.builder(Collections.singleton("scope"))
.build();
result = application.acquireTokenSilently(parameters).join();
}
catch (Exception ex){
if(ex instanceof MsalInteractionRequiredException){
// AcquireToken by either AuthorizationCodeParameters or DeviceCodeParameters
} else{
// Log and handle exception accordingly
}
}
I'm using org.keycloak:keycloak-admin-client:12.0.4. I've been doing some research about how to use the API.
Here are a couple examples:
// ----
// Getting a JWT
// ----
Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl("http://localhost:8180/auth")
.grantType(OAuth2Constants.PASSWORD)
.realm("dev")
.clientId("example-client")
.clientSecret("1169ef64-ea8f-47eb-9e55-74fdda9ee398")
.username("user1")
// raw password
.password("user1Pass")
.resteasyClient(
new ResteasyClientBuilderImpl()
.connectionPoolSize(10).build()
).build();
AccessTokenResponse atr =
keycloak.tokenManager().getAccessToken();
// ----
// Creating a new user
// ----
UserRepresentation user = new UserRepresentation();
user.setEnabled(true);
user.setUsername("tester1");
user.setFirstName("First");
user.setLastName("Last");
user.setEmail("example#email.com");
user.setAttributes(Collections.singletonMap("origin", Arrays.asList("demo")));
RealmResource realmResource = keycloak.realm("dev");
UsersResource usersRessource = realmResource.users();
Response response = usersRessource.create(user);
String userId = CreatedResponseUtil.getCreatedId(response);
CredentialRepresentation passwordCred = new CredentialRepresentation();
passwordCred.setTemporary(false);
passwordCred.setType(CredentialRepresentation.PASSWORD);
// raw password
passwordCred.setValue("test");
UserResource userResource = usersRessource.get(userId);
So in both of these situations, I'm using a String which is the raw password. My question is, should I be hashing passwords before sending them to Keycloak?
It's not that I distrust Keycloak, I'm just curious if Keycloak itself is doing some hashing in its own implementation. I've done some searching on Google, but haven't found any what I'm looking for.
I'd like to have from an admin user the context of the current loggin user.
For that, I use the admin token to have the current one with the function impersonateUser() because I don't have the password of the user.
I have the following error when I call the impersonateUser() on the Authentication object :
javax.xml.ws.soap.SOAPFaultException: OTDS username and password are required.
Here my example :
URL authLocation = new URL("http://localhost:8080/les-services/services/Authentication?wsdl");
String aToken = WebServiceUtil.getAuthenticationToken(authLocation, username, password);//admin token
OTAuthentication fOTAuth = new OTAuthentication();
fOTAuth.setAuthenticationToken(aToken);
com.opentext.livelink.service.core.Authentication auth = webServiceUtil.getAuthenticationService(authLocation);
String token = auth.impersonateUser(newUser);
fOTAuth.setAuthenticationToken(token);
I also found a class ImpersonateUser but I don't know how to use it :
ImpersonateUser impUser = new ImpersonateUser();
impUser.setUserName(newUser);
Do you have any advice ?
Thanks !
Here are the docs for the ImpersonateUser() method.
I have recently started playing with the Bing Ads api for managing my ads and campaigns and I am having problem in authenticating user (not oauth authentication).
I authenticated my user using oauth by the following
private String devToken = "ZZZZZ";
private String clientId = "AAA0BBB-XXXX-AAAAA";
protected static String UserName = "a.v#h.c";
protected static String Password = "********";
// To get the initial access and refresh tokens you must call requestAccessAndRefreshTokens with the authorization redirection URL.
OAuthTokens tokens = oAuthDesktopMobileAuthCodeGrant.requestAccessAndRefreshTokens(url);
System.out.println("Access token: " + tokens.getAccessToken());
System.out.println("Refresh token: " + tokens.getRefreshToken());
authorizationData = new AuthorizationData();
authorizationData.setDeveloperToken(getDevToken());
authorizationData.setAuthentication(oAuthDesktopMobileAuthCodeGrant);
This authenticates my user just fine since I can use the ICustomerManagementService.class just fine for accounts related information
customerServiceClient = new ServiceClient<>(authorizationData, ICustomerManagementService.class);
ArrayOfAccount accounts = searchAccountsByUserId(user.getId());
The above works perfectly. But when I try to do the same with ICampaignManagementService.class like below
campaignServiceClient = new ServiceClient<>(authorizationData, ICampaignManagementService.class);
GetAdsByAdGroupIdRequest cReq = new GetAdsByAdGroupIdRequest();
cReq.setAdGroupId(1234567890L);
campaignServiceClient.getService().getAdsByAdGroupId(cReq);
I get error code 106 saying that the user is not authorized.
The user does not represent a authorized developer.
106
Any help in this regard ?
Please try to set the CustomerId and CustomerAccountId header elements (CustomerId and AccountId of AuthorizationData). These headers are not available with the Customer Management service, but are applicable for Campaign Management service. If that does not resolve the issue please feel free to send the SOAP request + response to support for investigation. I hope this helps!
I'm working with Openfire and XMPP. My problem is: whenever I want to sign someone up I need to log into Openfire, like this.
connection.login(Username, Password);
AccountManager accountManager = AccountManager.getInstance(connection);
accountManager.createAccount(Username1, Password1);
So, how can I avoid this useless login?
Thank you.
You have to split login functionality from createAccount().
You must connect on Openfire server (without provide user and password), then ask for createAccount
//...connection builder
connection.connect();
AccountManager.getInstance(connection).sensitiveOperationOverInsecureConnection(true);
username = username.toLowerCase();
Map<String,String> attributes = new HashMap<String, String>(2);
attributes.put("name", fullName);
attributes.put("email", email);
AccountManager.getInstance(connection).createAccount(username, password, attributes);
//now you can do connection.login(username,password)