OpenAM : How to create the profile on login dynamically - openam

I developed a custom authentication module in OpenAM, and when user logins with this module.
I have to set "User Profile" to be ignored for a successful login. Otherwise it fails with error User Requires Profile to Login
OpenAM is correct because the logged-user does not exist in its OpenDJ datastore.
My question is:
How to create the profile dynamically on login?
It should be done in auth module or post-auth module?
Do I need write to OpenDJ datastore directly? or is there some helper class to do this?
Thanks in advance

It's possible to let OpenAM dynamically create user accounts if the user profile doesn't already exist in the configured data stores. To do so, you'll need to change the User Profile mode to Dynamic (see picture above).
If you want to control the attributes used to populate the freshly created user, then you will need to call #setUserAttributes with a Map<String, Set<String>> in AMLoginModule, and those values will be obeyed. The username used by OpenAM will be the name that you return in the #getPrincipal method.

Related

Can't reset B2C account password create via the Graph API

Hoping someone can shed some light on the following matter;
I got an Angular & .Net core Web API application that uses Azure B2C to authenticate users.
User accounts are created by the users themselves via the signin/signup custom policy or administrator can create accounts via the app using the Graph API.
Due to the requirements, the app uses usernames (as opposed to email addresses) to log into the application. So far I've managed to get everything working except for the following scenario:
When an account is created via the Graph API, the owner of that account cannot reset the account's password. The error is "An account could not be found for the provided user ID".
This isn't the case for accounts that get created via the custom signup policy so I did some comparison and found that for those account that get created via the Graph API, the Email is missing (which can be found under User -> Authentication Methods). I looked at populating that field, but it appears the "Mail" attribute is 'read only' (not sure if that's the right attribute anyway).
At the moment I'm having to manually set the email via Azure so those account's passwords can be reset by their owner if necessary. This is obviously not ideal and wanted to see if there is anyone that might have gotten around this issue, or a least get confirmation that this is indeed a limitation of the Graph API.
Thanks in advance for your help
So I managed to get this working using the approach outlined by Jas Suri. These are the steps that I went through
Created a custom attribute in my B2C tenant to hold the account email address
Included the custom attribute claim type (extension_emailAddress) as well as the strongAuthenticationEmailAddress in the TrustFrameworkBase.xml
Updated my apps's custom policies to include the technical profile for local account discovery. I basically just copied the necessary bits and pieces from here
Updated the local account discovery to perform the comparison against the extenstion_emailAddres instead of strongAuthenticationEmailAddress.
Added an extra step to the Sign up user journey so that the value in strongAuthenticationEmailAddress is copied to extension_emailAddress
Updated my Web API / Graph API "create user" function so that it sets the extension_appidguid_emailAddress
That's it. Now it doesn't matter how the account gets created, the email address will be stored in the extension attribute and the password reset will be able to find the account using that attribute.
happy to provide more details if anyone comes across this.
The problem is as you’ve identified, the Sign Up policy uses the strongAuthEmail attribute to store the verified email for a username based account. The Password reset policy will use this to verify the user owns the username. When creating the user with graph api, you can’t populate this field, it’s not exposed. The only option is to use a custom policy which stores this secure email in an extension attribute, and your graph api created users can then also target the same attribute to allow the stars to align.
Mail attribute is not the same as the Email under Authentication Methods, and currently there is no such graph api to set the Email value under Authentication Methods.
By the way, there is no need to create Azure AD B2C user for a user as users can sign up themselves.

Custom Azure B2C Password Reset Flow via Username

I setup a password reset flow using Azure B2C and local Azure accounts that uses the user's email address and verification code. However, my client would like to have a password reset email sent to the user based on the user name, not email address. The user email would be looked-up behind the scenes and an email sent that would include a link to the password reset page as shown in the flow below.
After reading a gazillion articles on custom Azure B2C policies, I'm struggling to convince myself if it is possible to do what the client is asking for using Azure B2C.
In the sample password reset flow shown below, some of the areas I'm struggling with include:
Is it possible to create custom pages in the password reset flow such as the page in Step 4 that displays the user's masked email address, or the information page in Step 7?
Is there built-in functionality to look-up a user's email address and Active Directory Object ID based on their user name or would I have to call out to a custom Azure Function and use the Graph API to do this?
Is it possible to create and send a custom email that includes a hyperlink to the password reset page that includes the user's Active Directory Object ID as a query string parameter so the password reset page knows which user's password is being reset?
At the moment, it seems like it would be easier to create a completely custom ASP.NET MVC app to handle the requirements than it would be to use Azure B2C custom policies, but that isn't really a path I want to go down.
Is it possible to create custom pages in the password reset flow?
Yes you can create your own custom password reset user flow using azure active
directory B2C
In your case if you want to figure out your custom page you could
refer here
Is there built-in functionality to look-up a user's email address and
Active Directory Object ID based on their user name or would I have
to call out to a custom Azure Function and use the Graph API to do
this?
Using Microsoft Graph REST API you could fetch your user
information.
In your case you could use
List users
Get a user
To access user information you could also refer here in a great
details
Is it possible to create and send a custom email that includes a
hyperlink to the password reset page that includes the user's Active
Directory Object ID as a query string parameter so the password reset
page knows which user's password is being reset?
You can use the company branding feature to customize the
content of verification emails for resetting password.
Note : For better clarity you could check the Azure AD B2C: Frequently asked
questions (FAQ) before final work around Which definitely guide you to
define ultimate go ahead.
Update
As per Microsoft document right now you cannot create according to your sample exactly. See the screen shot there is and important remarks.
Thank you.
This GitHub project covers the case you describe. Still needs a lot of understanding about custom flows to get it working.
https://github.com/yoelhor/aadb2c-verification-link

Scenarios definition for JWT/API Process with Cucumber/Behat

I have a scenario where basically:
- Authorized (JWT) user access my API
- If user exists, info get synched with DB, if not, gets created
- ETC ETC
My question is, how would I proceed creating this scenario? There's a lot (ok, 4) parameters that should be in the request, but I don't want to polute the scenario with information that can confuse a normal user reading the scenario.
This is what I have:
Scenario: Non Existent user access the API
Given an authorized user access the API
And user does not exist on API database
When user access the API
Then user details are added to API database
And user does exist on API database
A user accessing the api will have: email, auth0_id, nickname and name. Just not sure if I should code those info on the Scenario or somehow do it on the Context file.
Edit:
Can I have some "parameters" to be set IN the Context file, instead of in the .feature file? i.e. On the feature file I say "Non existent user access the application" and inside the Context file, in the function associated with this step, I make sure I create a user that does not exist on the database and so on? Would this be a good way of keeping thinks separated from the .feature scenarios?
Thanks
I would write it like this:
Scenario: API - new user access the API
Given I have a new user
When I access the API with the new user
Then the user is added to the API database
First step would generate the user details and save them in a variable, second would make the call to the api (using the saved variable and generate the JWT) and the last one will check the details in the api.
You can declare new as parameter like:
#Then /^I access the API with the (new|other_user) user$/
Anyway, you should declare it as simple as possible in a manner that has sense to you can that you can easily reuse.

Simulate signin/login using Symfony/sfDoctrineGuardPlugin

In a situation, where the user is authenticated on another application (like oAuth or a custom security implementation), how can we simulate login?
What we intend to achieve is:
- use the user identifier key to check if the user exists
- if the user exists, set-up the session for the user
- basically, setup the attribute holder
- assign the user object, so that it is available thru getUser() method
So we are looking at signing-in programatically!
Any light on how do it in the simplest way?
if using sfDoctrineGuardPlugin, i'd do something like:
Redirect user to 3rd part oAuth provider
On success, user returns to you, either create them a new sfGuardUser object, or retrieve the appropriate one (you may need to adapt the schema to have somewhere to store extra oAuth data).
Call myUser()->signIn($user), where $user in the previously retrieved sfGuardUser object - eg: I use this in register actions to log people in after registration: $this->getUser()->signin($user);

Liferay - Custom Authentication Web Service. Do not need user info in liferay db

I have followed Custom Authentication Web Service link to customize authentication.
But Liferay is still checking whether the same user email id is configured in the liferay db or not. If its not, it is saying that authetication failed.
I do not want to keep any user information in the liferay db. Do any one know how to do that?
Regards
Vishal G
Create dummy users for your real users with fake data. Liferay requires some sort of Liferay user in the database to function correctly. You can create one dummy user for each real user or one dummy user for all your users depending on your needs.

Resources