OpenAM : Can't login with custom authentication module - openam

I developed a custom authentication module by following the example and installed into top level realm. OpenAM 11.0.0.
Then I open the test page for my auth module.
The login fails with the error "Login/password combination is invalid."
However, if I open /openam after seeing this error message, it says I am logged-in.
Here is the process code of the AMLoginModule
public int process(Callback[] callbacks, int state) throws LoginException
{
if (debug.messageEnabled())
{
debug.message("Authentication module process() is called. state: " + state);
}
switch (state)
{
case STATE_BEGIN:
// No time wasted here - simply modify the UI and
// proceed to next state
substituteUIStrings();
return STATE_AUTH;
case STATE_AUTH:
return ISAuthConstants.LOGIN_SUCCEED;
case STATE_ERROR:
return STATE_ERROR;
default:
throw new AuthLoginException("invalid state");
}
}
You can see any username / password is accepted. The debug log shows that the module is called correctly.
[root#a3652f4b6f0f debug]# tail /openam/openam/debug/em
em:06/15/2015 06:58:20:462 AM UTC: Thread[http-bio-8080-exec-4,5,main]
Authentication module process() is called. state: 1
em:06/15/2015 06:58:20:540 AM UTC: Thread[http-bio-8080-exec-4,5,main]
Authentication module process() is called. state: 2
em:06/15/2015 06:58:27:501 AM UTC: Thread[http-bio-8080-exec-4,5,main]
Authentication module init() is called
em:06/15/2015 06:58:27:507 AM UTC: Thread[http-bio-8080-exec-4,5,main]
Authentication module process() is called. state: 1
em:06/15/2015 06:58:27:625 AM UTC: Thread[http-bio-8080-exec-4,5,main]
Authentication module process() is called. state: 2
Please why do I see the error "Login/password combination is invalid." in test login page?

The problem is that you don't have user profile to login. You need to have the username in your datastore which you pass to SampleAuthPrincipal("username") constructor .
#Override
public Principal getPrincipal() {
return new SampleAuthPrincipal("username");
}
This should resolve your problem.

Related

Trying to get property 'id' of non-object This Error comes in that Function

public function productTrackOrder(Request $request)
{
$order=Order::where('user_id',auth()->user()->id)->where('order_number',$request->order_number)->first();
You can access the user id via the Auth facade.
Auth::id()
However, always do a check to be share that the user is logged in to avoid a non object-error
use Illuminate\Support\Facades\Auth;
// can always check if the user is logged in before running your query
if (Auth::check()) {
$order=Order::where('user_id',Auth::id())-
>where('order_number',$request->order_number)->first();
}

Using 2FA for password reset

My application uses Asp.Net Identity and sends a Two Factor code to my Auth app on login. This is pretty standard (as there lots of examples on the net) and uses the SendCode() method. My understanding is that the 'magic' is done by this line:
// Generate the token and send it
if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
{
View("Error");
}
My requirement is to ensure the user goes through the same process of 2FA when they want to change their password after they have logged in.
My issue is that when the code to send the 2FA code is executed:
if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
{
View("Error");
}
I receive the error 'UserID not found':
Server Error in '/MSPortal' Application.
UserId not found.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: UserId not found.
Source Error:
Line 555:
Line 556: // Generate the token and send it
Line 557: if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider))
Line 558: {
Line 559: return View("Error");
I know SendTwoFactorCodeAsync() calls GetVerifiedUserIdAsync() but my understanding is that the user is verified now that I have already logged in using 2FA.
Does anyone know why I would be getting this error?
Thanks.
I've worked around this by overriding SendTwoFactorCodeAsync() in IdentityConfig.cs. In this override, I first call GetVerifiedUserIdAsync() as per usual but then if that is 0 I get the User's ID from the Current HttpContext.
I am not stating this is the best way but it's what I have done thus far and its got me moving ahead in my aim of having 2FA for login, change password and forgot password.
The code (likely to go through some refactoring if I get feedback) is:
public override async Task<bool> SendTwoFactorCodeAsync(string provider)
{
int userId = 0;
try
{
userId = await GetVerifiedUserIdAsync();
if (userId == 0)
{
userId = Convert.ToInt32(HttpContext.Current.User.Identity.GetUserId());
}
if (userId == 0)
return false;
}
catch
{
return false;
}
var token = await UserManager.GenerateTwoFactorTokenAsync(userId, provider);
// See IdentityConfig.cs to plug in Email/SMS services to actually send the code
await UserManager.NotifyTwoFactorTokenAsync(userId, provider, token);
return true;
//return base.SendTwoFactorCodeAsync(provider);
}

auth0 callback doesn't set profile date after login angular2

I have an angular 2 app which uses auth0 for authentication. The issue I'm having is that when a successful login occurs, it seems like the lock callback is not being called. Only after I do a manually refresh of the page will the profile data be sent to local storage.
When a user logs in, I need to grab that profile object and use it within the component class. This code works only after I manually refresh the page following a successful login. Here is my code (only including the important parts).
auth.service
lock = new Auth0Lock('.....9cNzyzJ3DZc2VpDyXSYF5', '.....12.auth0.com', {});
user: any;
constructor() {
// Add callback for lock `authenticated` event
this.user = JSON.parse(localStorage.getItem('profile'));
this.lock.on("authenticated", (authResult:any) => {
this.lock.getProfile(authResult.idToken, function(error: any, profile: any){
if(error){
throw new Error(error);
}
localStorage.setItem('id_token', authResult.idToken);
localStorage.setItem('profile', JSON.stringify(profile));
this.user = profile;
});
});
}
public login() {
// Call the show method to display the widget.
this.lock.show();
console.log('login func');
};
nav.component
constructor(private auth: Auth, private groupsService: GroupsService){
}
ngOnInit(){
// need to access the profile object here. Ocject is correctly logged only after refreshing.
console.log(JSON.parse(localStorage.getItem('profile')));
this.groupsService.getGroups(this.userId).subscribe(groups => {
this.groups = groups;
// sort the groups
this.groups.sort((a, b) => new Date(b.date_created).getTime() - new Date(a.date_created).getTime());
});
}
According to the documentation for ngOnInit:
ngOnInit is called right after the directive's data-bound properties have been checked for the first time, and before any of its children have been checked. It is invoked only once when the directive is instantiated.
(emphasis is mine)
Which indicates that when its run there isn't a user profile available yet because the authentication was still not processed. If you cause a page refresh after authentication, the user profile is already available in Web Storage and the manual refresh causes the ngOnInit to be executed leading to the behavior you described.

Azure Active Directory: Where can I insert a function to run after a user is signed in?

I've been following this example https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-devquickstarts-web-dotnet/ and I'm pretty certain that in the SignIn method I can put my function there to run, but I'm not sure how you would go
In that top portion of the AccountController.cs example:
namespace WebApp_OpenIDConnect_DotNet_B2C.Controllers
{
public class AccountController : Controller
{
public void SignIn()
{
if (!Request.IsAuthenticated)
{
// To execute a policy, you simply need to trigger an OWIN challenge.
// You can indicate which policy to use by adding it to the AuthenticationProperties using the PolicyKey provided.
HttpContext.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties (
new Dictionary<string, string>
{
{Startup.PolicyKey, Startup.SignInPolicyId}
})
{
RedirectUri = "/",
}, OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
Where do I insert toDoAfterSignedIn(); method ? or is this the wrong way of doing it, is there some listener or event emitter that will notify me when a user has successfully signed in?
https://github.com/AzureADQuickStarts/B2C-WebApp-OpenIdConnect-DotNet
The correct place to plug-in yourself is the Startup.Auth.cs file. And register yourself for one of the OpenIdConnectNotifications. The notification you need is SecurityTokenValidated. And you will need to add it similarly to the other two notifications which are already in the sample. Or just add the following line within the the OpenIdConnectnotifications initializer:
SecurityTokenValidated = (notification) => {
return Task.Delay(0);
}
The notification parameter you get contains everything you need to know about the end user and his/her successfull authentication.

FBA Authentication and Security Token Error

There is a login form with any authentication logic. I enter login and password, then I click "Login" and get error "The method or operation is not implemented" in this code line:
SecurityToken tk = SPSecurityContext.SecurityTokenForFormsAuthentication
(
new Uri(SPContext.Current.Web.Url),
"MyUserProvider",
"MyRoleProvider",
this.txLogin.Text,
this.txPassword.Text
);
================================================
Server Error in '/' Application.
The method or operation is not implemented.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ServiceModel.FaultException`1[[System.ServiceModel.ExceptionDetail, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]: The method or operation is not implemented.
Stack Trace:
[FaultException`1: The method or operation is not implemented.]
Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel.ReadResponse(Message response) +1161013
Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel.Issue(RequestSecurityToken rst, RequestSecurityTokenResponse& rstr) +73
Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel.Issue(RequestSecurityToken rst) +36
Microsoft.SharePoint.SPSecurityContext.SecurityTokenForContext(Uri context, Boolean bearerToken, SecurityToken onBehalfOf, SecurityToken actAs, SecurityToken delegateTo) +26193297
Microsoft.SharePoint.SPSecurityContext.SecurityTokenForFormsAuthentication(Uri context, String membershipProviderName, String roleProviderName, String username, String password) +26189452
Microsoft.SharePoint.IdentityModel.Pages.FormsSignInPage.GetSecurityToken(Login formsSignInControl) +188
Microsoft.SharePoint.IdentityModel.Pages.FormsSignInPage.AuthenticateEventHandler(Object sender, AuthenticateEventArgs formAuthenticateEvent) +123
System.Web.UI.WebControls.Login.AttemptLogin() +152
But I have assembly with custom Membership and Roles Provider and all methods are implemented! Where is a mistake?
You may be calling base membership functions directly from your custom membership and roles provider, like:
Membership.FindUsersByEmail("myemail#here.com");
These will get handled by the default membership provider, which won't be your membership provider, but will be the SPClaimsAuthMembershipProvider. SPClaimsAuthMembershipProvider doesn't implement a lot of the base methods - they will return a not implemented exception.
If you want to get the web app's selected membership provider to reference, you can use the following code:
public static string GetMembershipProvider(SPSite site)
{
// get membership provider of whichever zone in the web app is fba enabled
SPIisSettings settings = GetFBAIisSettings(site);
return settings.FormsClaimsAuthenticationProvider.MembershipProvider;
}
public static SPIisSettings GetFBAIisSettings(SPSite site)
{
SPIisSettings settings = null;
// try and get FBA IIS settings from current site zone
try
{
settings = site.WebApplication.IisSettings[site.Zone];
if (settings.AuthenticationMode == AuthenticationMode.Forms)
return settings;
}
catch
{
// expecting errors here so do nothing
}
// check each zone type for an FBA enabled IIS site
foreach (SPUrlZone zone in Enum.GetValues(typeof(SPUrlZone)))
{
try
{
settings = site.WebApplication.IisSettings[(SPUrlZone)zone];
if (settings.AuthenticationMode == AuthenticationMode.Forms)
return settings;
}
catch
{
// expecting errors here so do nothing
}
}
// return null if FBA not enabled
return null;
}
Some things to try:
Did you register the providers in the web application through the Cental Admin?
Did you register the providers in your web.config?
What happens if you use SPClaimsUtility.AuthenticateFormsUser instead?

Resources