WSO2 Username matching between MFA steps - wso2

I have an existing CAS Service Provider and I need to add multifactor authentication via AzureAD. I have it configured and "working", but the user can specify different accounts to gain access, and I want to require them to use the same username in both CAS (MFA step 1) and AzureAD (MFA step 2).
I have reviewed XACML policies, but I haven't found any documentation that indicates the policies can evaluate attributes from multiple authentication methods. Am I missing something or is XACML policy the wrong technology for accomplishing our use case of requiring the same username on both authentication methods?

Yes, you can't use XACML to achieve this use case. Because this is XACML policy can be applied after full authentication, but this use case is inside the authentication flow.
If you are using WSO2 IS 5.7.0, You can achieve this use case using adaptive authentication scripts
You need to just write the authentication script to compare the username of the both steps
function onLoginRequest(context) {
executeStep(1, {
onSuccess: function (context) {
executeStep(2, {
onSuccess: function (context){
if (!context.steps[1].subject.username != context.steps[2].subject.username) {
//
sendError('http://www.example.com/error',{'errorcode':'000403','errorMsg':'You are not allowed to login to this app.'});
}
}
});
}
});
}
If you are using older versions of IS, you need to write a custom authenticator for the same logic and add to the IS. Then add this authenticator as 3rd step.

Related

Can I define static claims to be returned to a Service Provider?

I have a use-case where a SAML2 application expects certain attributes in the SAML2 assertion. These are not present in user attributes, but they should have static values which are returned in every SAML2 assertion for that service provider.
Is there any way to define such static attributes/claims in WSO2 IS admin console? I know I could create a custom claims handler with Java, but I'm looking first for solutions not requiring custom code.
This issue was similar, but the answer didn't apply to the general case: wso2is any way to code claim to return static text
You can use an Adaptive Authentication script for this. (Simple scripting supported via Management Console)
Example :
function onLoginRequest(context) {
executeStep(1, {
onSuccess: function (context) {
var user = context.currentKnownSubject;
var countryClaim = 'http://wso2.org/claims/country';
var countryValue = user.localClaims[countryClaim];
if (countryValue == null){
Log.info('Updating the address - country claim for user.');
context.steps[1].subject.localClaims[countryClaim] = 'Canada';
}
Log.info('Testing of adding default claim value to user.');
}
});
}
Documentation
Adaptive Authentication
Adaptive Authentication JS API Reference

AWS Cognito custom auth flow with USER_PASSWORD_AUTH

I'm currently working on a custom authentication flow, using the define, create and verify triggers. However, the users password isn't checked during the flow. We use the USER_PASSWORD_AUTH option on our clients, so no SRP.
I saw this question Can I use the migration trigger in a Custom auth flow and didn't quite make out if it answered my question:
Is it possible to use custom auth flow in combination with username-password (non-SRP) flow? And if so, what is the challenge name that I have to return?
Here is stated that combinations can be used, but it seems to me that the PASSWORD_VERIFIER only works with the SRP auth:
A custom authentication flow can also use a combination of built-in challenges such as SRP password verification and MFA via SMS, and custom challenges such as CAPTCHA or secret questions.
So I managed to add the password challenge to the custom auth flow, by returning it as the first challenge in the DefineAuthChallenge lambda trigger, like this:
// Add the password verifier to verify the password first.
if (input.Request?.Session == null || !input.Request.Session.Any(s => s.ChallengeName == "PASSWORD_VERIFIER"))
{
input.Response.ChallengeName = AuthChallengeNames.AWS_PasswordVerifier;
input.Response.FailAuthentication = false;
input.Response.IssueTokens = false;
return input;
}
No challenges are given in the session, as this should be the first challenge to be returned by the custom auth flow, as described here (section 'Custom Authentication Flow'):
If you want to include SRP in a custom authentication flow, you need to start with it.
However, at the moment, if a user is forced to change their password, the custom auth flow is skipped afterwards, which is a bug at the moment, confirmed by AWS. See related post here.
The example here (section 'Define Auth Challenge Example') proved to be blatantly wrong, as there are no challenges in the session the first time the define auth challenge trigger is hit.

Combine client_credentials and Custom authentication flow in Cognito?

Wondering if it's possible to combine using the client credentials OAuth flow in Cognito with a custom authentication flow as described here: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html
I know about custom authentication flows in Cognito, but I am not so well versed in OAuth itself. But as far as I understand it, the client credentials flow, is unrelated to a user? Because in that case, I would think it is impossible to use a custom authentication flow since the SDK documentation states the following (taken from the AWS node.js SDK):
The authentication parameters. These are inputs corresponding to the AuthFlow that you are invoking. The required values depend on the value of AuthFlow:
[...] For CUSTOM_AUTH: USERNAME (required)
If the value passed as USERNAME in the CUSTOM_AUTH flow is not a known user in Cognito, the lambda trigger for the custom flow will never be executed. And since it is never executed, it is not possible to use the USERNAME parameter to pass any other data to the lambda trigger (you can of course use custom authentication parameters, but you also need a valid USERNAME).

Amazon AWS getAttribute() using AWS.config.credentials

I have just started with Amazon Cognito and I want to use it for my web application. I want to develop a stateless app, in which I SignUp/SignIn using Cognito and then using the JWT token in rest of the requests.
I have implemented sign-up and sign-in flow in Node.js using amazon-cognito-identity-js package and then using the JWT token to call a lambda function using aws-sdk. Things are as expected till here.
But now the issue is with different user operations like get attribute, verify attribute, update password etc. as listed #
https://docs.aws.amazon.com/cognito/latest/developerguide/using-amazon-cognito-user-identity-pools-javascript-examples.html
All of these operations require cognitoUser object and in the documentation they are using userPool.getCurrentUser(); expression.
And I have read somewhere that this method returns the last authenticated user. So I think this expression userPool.getCurrentUser(); will cause conflicts. For example if UserB logs in after UserA and UserA tries to update his password, it will not work.
Can someone suggests me what are the possible solutions?
Should I store the cognitoUser object in session at server side ?
[This solution breaks my stateless requirement and I will have to maintain session on server side.]
Is there any way to perform these operations using JWT token ?
Please suggest if you can think of any other better approach to implement Cognito in web app.
Thanks.
We have a stateless app using cognito and lambdas.
The way we have set it up is to not call lambdas directly but to use Api Gateway and lambda-proxy integration.
If you call lambdas directly from your front end code and are using the cognito tokens for authentication then you need to put a lot of logic in each lambda to validate the token, e.g. download the relevant keys, check the signature of the jwt, timestamps, issuer etc. If you use API gateway then you can just create a cognito authorizer and place it in front of your lambdas.
We pass the id_token when making api calls, then the call is validated by the authorizer and the lambda receives all the current attributes set up in the user pool. This means we don't need to make additional calls to get attributes.
For changing the user passwords this can be done from the front-end of the app by calling the cognito api with the access_token if you have allowed it in the user pool client setup.

How to perform WSO2 user authentication

How will you authenticate a user created in WSO2? I need to check if the password entered by the user is correct before performing some function. Are there any SCIM apis for this?
There are several APIs you can use to authenticate user.
RemoteUserStoreManagerService (SOAP service)
SCIM2 API (you can use /scim2/Me GET method for this, though this API is not specifically design for this)