msal4j - WsTrust endpoint not found in metadata document - java

I am using msal4j library (1.9.1 version) to perform authentication, using OUTH2.0 and OpenId with Azure Active Directory, in the end I need to acquire token.
I was requested to do this operation through a proxy, so i tried to use code I found in msal4j documentation:
Proxy proxy = new Proxy( Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
proxyUser,
proxyPassword.toCharArray() ) ;
}
});
Set<String> scope = Collections.singleton("User.Read");
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build();
PublicClientApplication pca = PublicClientApplication.builder(clientId)
.httpClient(new MyHttpClient(proxy,sslContext.getSocketFactory(), 0, 0))
.authority("https://login.microsoftonline.com/organizations").build();
UserNamePasswordParameters paramaters = UserNamePasswordParameters
.builder(scope, user, password.toCharArray()).build();
//here I get the error
IAuthenticationResult result = pca.acquireToken(paramaters).join();
but I am getting this error on acquireToken method
java.util.concurrent.ExecutionException:
com.microsoft.aad.msal4j.MsalServiceException: WsTrust endpoint not
found in metadata document at
java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at
java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908)
Caused by: com.microsoft.aad.msal4j.MsalServiceException: WsTrust
endpoint not found in metadata document
I also tried get method instead of join, but same result.

On Workaround on this Error:
java.util.concurrent.ExecutionException:
com.microsoft.aad.msal4j.MsalServiceException: WsTrust endpoint not
found in metadata document
Using a global tenant administrator account, which is your .onmicrosoft.com account.
Please verify and make sure you have logged in with the proper account for the App you registered. This error usually occurs if you are using the wrong credentials.
username = xxxx#xxxx.onmicrosoft.com
Note: integrated Windows Authentication (IWA) supports federated users only - users created in Active Directory and backed by Azure AD. Users created directly in Azure AD without Active Directory backing (managed users) can't use this authentication flow.
For more details refer this document
For more details refer this SO Thread: WsTrust endpoint not found in metadata document

Related

Azure Blob Storage blob access from Azure Active Directory (Azure AD) authentication

ClientSecretCredential clientSecret = new ClientSecretCredentialBuilder()
.clientId("********-****-****-****-************").tenantId(
"********-****-****-****-************")
.clientSecret("*****~***************************~******").build();
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.credential(clientSecret)
.endpoint("https://sambhutestsa.blob.core.windows.net/")
.buildClient();
BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient("testcontainer");
System.out.printf("Identifier for the snapshot is %s%n", blobContainerClient.getBlobClient("2824891.jpg").downloadToFile("C:\\Users\\ss255248\\2824891.jpg");
but getting this error can someone please help here.
Exception in thread "main" com.azure.storage.blob.models.BlobStorageException: If you are using a StorageSharedKeyCredential, and the server returned an error message that says 'Signature did not match', you can compare the string to sign with the one generated by the SDK. To log the string to sign, pass in the context key value pair 'Azure-Storage-Log-String-To-Sign': true to the appropriate method call.
If you are using a SAS token, and the server returned an error message that says 'Signature did not match', you can compare the string to sign with the one generated by the SDK. To log the string to sign, pass in the context key value pair 'Azure-Storage-Log-String-To-Sign': true to the appropriate generateSas method call.
Please remember to disable 'Azure-Storage-Log-String-To-Sign' before going to production as this string can potentially contain PII.
Status code 403, "<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthorizationPermissionMismatch</Code><Message>This request is not authorized to perform this operation using this permission.
RequestId:d813ea5f-d01e-004d-7b0f-656de3000000
Time:2022-05-11T08:13:50.0902556Z</Message></Error>
To resolve the error, please try the following:
Make sure whether you have below roles assigned to your security principal:
Storage Blob Data Contributor
Storage Blob Data Owner
If not, make sure to assign it like below:
Go to Azure Portal ->Identify the required scope (Subscription/Resource group) -> Access Control (IAM) -> Add Role assignment
Check whether your application has below API permissions:
For more information, please refer this MsDoc:
Otherwise, try setting the time zone to UTC-0 .
Try adding comp=list&restype=container to your SAS URL as a workaround.
Make use of the snippet suggested in this SO thread.
For more in detail, please refer below link:
Azure App Service rejected with 403 error by Storage Account - Stack Overflow
[Solved] Azure Shared Access Signature - Signature did not match - Local Coder

OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token

Why I am not able to call graphClient more then once?
Code:
public static void initializeGraphAuth(String authorizationCode) {
List<String> scopes = new ArrayList<>();
scopes.add("https://graph.microsoft.com/mail.read");
// Create the auth provider
final AuthorizationCodeCredential authCodeCredential = new AuthorizationCodeCredentialBuilder().clientId(AzureConstants.CLIENT_ID).clientSecret(AzureConstants.CLIENT_SECRET).authorizationCode(authorizationCode) .redirectUrl(AzureConstants.REDIRECT_URI).build();
authProvider = new TokenCredentialAuthProvider(scopes, authCodeCredential);
// Create default logger to only log errors
DefaultLogger logger = new DefaultLogger();
logger.setLoggingLevel(LoggerLevel.ERROR);
// Build a Graph client
graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).logger(logger).buildClient();
}
public static User getUserDetails() {
return graphClient.me().buildRequest().get();
}
public static List<Group> getUserGroups() {
GroupCollectionPage groups = graphClient.me().transitiveMemberOfAsGroup().buildRequest().get();
return groups.getCurrentPage();
}
In main app I am calling getUserDetails() and getUserGroups() methods to get users details and group details respectively. Able to get User details but not group details below is the error
com.microsoft.aad.msal4j.MsalInteractionRequiredException: AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token.
Trace ID: 48d1fee1-cb8b-48c6-a7ec-91e2b2057500
Correlation ID: c58388ec-417c-4398-82ee-68910568f4df
If i call only one method either getUserDetails or getUserGroups its is working fine, but when i call both methods in code it is giving error
How can i use graphClient object to get user and group details both??
Thanks for your help
When your application uses authorization codes to obtain tokens, this behavior is to be expected.
In this situation, refresh tokens can be used to obtain extra tokens for other resources.
Refresh tokens can be used several times across multiple resources, whereas authorization codes can only be used once.
When Credential uses a refresh token, it also updates the access token when the access token expires.
You can receive a new access token using a refresh token by using the Google OAuth2 client library.
For more information on this, you can refer OAuth 2.0 and the Google OAuth Client Library for Java
REFERENCES:
OAuth2 Authorization code was already redeemed - Microsoft Q&A
How to get an access token using a refresh token in Java? - Stack Overflow

keycloak offline token with Java

I am using authentication of users in Java 8 against Keycloak, with the Keycloak adapter API for Java.
In this case, the class KeycloakBuilder (keycloak-admin-client-6.0.0.jar) builds a Keycloak instance to perform authentication operations.
how can I request an offline token rather than a normal Bearer token using this API?
Have not found parameter or way to request it. I need tokens with 1 month expiration time, which cannot get unless change the "SSO Session Max" field, but I don´t want this to affect other Clients or users in the same Realm / client.
I am not sure if there are any specialties with the Keycloak Java adapter but I already implemented this with other clients. On the Authorization server side, you need to add a role offline_access to the users, which are allowed to request an offline session (this can be done explicitly or as a default role mapping). On the client side, you have to add another scope offline_access to the auth request. This can also be done by default (see default scopes). Please refer to the official Keycloak documentation about Offline Sessions for further details.
I post a possible solution using keycloak-authz-client library instead.
As stated by #Philipp , it is also necessary that the user you log in with has the role offline_access.
public String login(String username, String password) {
String authServerUrl = "http://localhost:18080/auth"; // Your keycloak auth entpoint
String realm = "realm"; // Realm
String clientId = "client"; // Client
Map<String, Object> clientCredentials = new LinkedHashMap<String, Object>();
clientCredentials.put("secret", "clientSecret"); // Client secret (Access Type: Confidential)
Configuration configuration = new Configuration(
authServerUrl,
realm,
clientId,
clientCredentials,
null
);
AuthzClient authzClient = AuthzClient.create(configuration);
AuthorizationRequest request = new AuthorizationRequest();
request.setScope("offline_access");
AuthorizationResponse response = authzClient.authorization(username, password).authorize(request);
return response.getRefreshToken(); // response.getToken() returns the bearer token
}

403 Forbidden error when reading mails through Graph API with valid JWT token

I need to read mails from an Outlook mailbox via Graph API. The application I am writing is a scheduled batch job without user interaction. I can't use application permissions, because of compliance reasons. The application must not be able to access all mailboxes on the tenant. I use delegated permissions for a technical user that got shared the allowed mailboxes to achieve that. I was able to get a JWT Access Token via ADAL4J and successfully called some APIs with it, but whenever I try to read a mailbox even the technical user mailbox I get a 403 forbidden.
I started with this official [sample] (https://github.com/Azure-Samples/active-directory-java-native-headless/). After setting up my Application in Azure this sample worked right away. I then changed the Graph call to "https://graph.microsoft.com/v1.0/me/messages" and suddenly I got a 403 Forbidden. To avoid permission problems I added all delegated permissions available in Azure AD to the application and provided Administrator consent for everything. That unfortunatly changed nothing. When I check the contents of my token I see the scp field containing all the permissions. Whats strange is that I can actually write the mailbox. I can write to the draft folder via Graph API. But when I take the returned message ID and try to query the same message I just created I again get a 403 Forbidden.
Getting the token
private static AuthenticationResult getAccessTokenFromUserCredentials(
String username, String password) throws Exception {
AuthenticationContext context;
AuthenticationResult result;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext(AUTHORITY, false, service);
Future<AuthenticationResult> future = context.acquireToken(
"https://graph.microsoft.com", CLIENT_ID, username, password,
null);
result = future.get();
} finally {
service.shutdown();
}
return result;
}
Calling the messages endpoint:
URL url = new URL("https://graph.microsoft.com/v1.0/me/messages");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setRequestProperty("Accept","application/json");
int httpResponseCode = conn.getResponseCode();
Change the api version to beta will solve this issue.
https://graph.microsoft.com/beta/me/messages

Uber Rides JAVA SDK : Unable to request token

I am new to using API in Java. I need to access Uber API's for my project and I am using Uber Java SDK from - https://github.com/uber/rides-java-sdk
I am following their steps but somehow getting error for Authenticating credentials. following are my steps:
1) Creating OAuth2Credentials object
SessionConfiguration config = new SessionConfiguration.Builder()
.setClientId(CLIENT_ID)
.setClientSecret(MY_SECRET)
.setRedirectUri(REDIRECT_URL)
.setScopes(Arrays.asList(Scope.HISTORY, Scope.PROFILE, Scope.PLACES))
.build();
OAuth2Credentials credentials = new OAuth2Credentials.Builder()
.setSessionConfiguration(config)
.build();
2) Navigate the user to the authorization URL from the OAuth2Credentials object.
String authorizationUrl = credentials.getAuthorizationUrl();
3) Once the user approves the request, you get an authorization code. Create a credential object to store the authorization code and the user ID.
Credential credential = credentials.authenticate(authorizationCode, userId);
** i am using "authorizationCode" returned to my REDIRECT_URL
** I am NOT sure what userID should be??
But really code fails at STEP 3 with error:
HTTP ERROR 500
Problem accessing /hello. Reason:
Unable to request token.
Caused by:
com.uber.sdk.rides.auth.AuthException: Unable to request token.
at com.uber.sdk.rides.auth.OAuth2Credentials.authenticate(OAuth2Credentials.java:279)
at com.c2p.HelloAppEngine.doGet(HelloAppEngine.java:183)
*** Please HELP:
1) How to resolve above error - am I doing anything wrong?
2) Are my steps correct?
3) What should be the UserID and where can i get that?
In order to get the user uuid you need to take the access token you get and make a request to https://developer.uber.com/docs/rides/api/v1-me.
UserProfile userProfile = uberRidesService.getUserProfile().execute().body();
See the java sample app included in the sdk: https://github.com/uber/rides-java-sdk/blob/master/samples/servlet-sample/src/main/java/com/uber/sdk/rides/samples/servlet/SampleServlet.java

Categories

Resources