identityserver / identityserver3.membershipreboot Goto Github PK
View Code? Open in Web Editor NEWMembershipReboot support for Thinktecture IdentityServer3
License: Apache License 2.0
MembershipReboot support for Thinktecture IdentityServer3
License: Apache License 2.0
When returning a user profile the updated_at
claim is off from the correct UTC value by the user's time offset.
E.g., user Bob has a LastUpdated date in the database of
2015-11-19T22:17:31
(UTC)
The updated_at
claim returns 11447989451
(UTC, obviously) which in human friendly form is
2015-11-20T03:17:31
It appears to be because in GetClaimsFromAccount
the following is called:
new Claim(Constants.ClaimTypes.UpdatedAt, IdentityModel.EpochTimeExtensions.ToEpochTime(account.LastUpdated).ToString(), ClaimValueTypes.Integer),
The date, which is already in UTC, is sent to ToEpochTime
in the IdentityModel library which then applies the UTC offset again:
public static long ToEpochTime(this DateTime dateTime)
{
var date = dateTime.ToUniversalTime();
var ticks = date.Ticks - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).Ticks;
var ts = ticks / TimeSpan.TicksPerSecond;
return ts;
}
Resulting in UTC +5hrs (the current offset for my region) or 03:17 on 2015-11-20.
This can be replicated in the samples library. I launched the MembershipReboot sample and created a sample account for Bob:
SELECT [ID]
,[Username]
,[Created]
,[LastUpdated]
FROM [IdentityServer3.MembershipReboot].[dbo].[UserAccounts]
ID Username Created LastUpdated
------------------------------------ -------- ----------------------- ------------
030493FF-C202-42E1-A372-C761F626A8B9 bob 2015-11-19 22:17:31.650 2015-11-19 22:17:31.650
And then used the WPF Implicit client to log in with profile and access token, called the userInfo endpoint and got back:
{
"sub": "030493ff-c202-42e1-a372-c761f626a8b9",
"updated_at": 1447989451,
"preferred_username": "bob"
}
As noted above, that epoch time corresponds to five hours ahead of the UTC time stored in the database.
I'm not sure if the solution is to add another epoch method to the IdentityModel library that skips the offset or to perform an offset either before or after sending the time to that method. (Or if I've missed something completely and this is a non-issue). For my own purposes I've overridden GetClaimsFromAccount
and use a different epoch conversion function.
I have a small project that uses IdentityServer3 w/ MembershipReboot (Thanks for the recommendation here Brock). I was utilizing a few claims in my client application, one being "sub" and another being a custom claim. All was working fine. I updated the nuget packages today to bring IdentityServer3.MembershipReboot up to version 2.0.0, BrockAllen.MembershipReboot up to 8.4 and IdentityServer3 up to 2.5.1. After the update, several claims have been dropped from the principal. I debugged the situation and the claims are being retrieved and properly added in the MR services (and my CustomClaimMapping class). Once the execution reaches line 141 in IdentityServer3.MembershipReboot.cs the await call is executed and nothing is returned and about 7 claims are dropped. I am trying to determine if they are being dropped even earlier.
I can't seem to retrieve the FirstName, LastName and Age property values as specified on the virtual properties in CustomUser? I am trying to modify the "GetClaimsFromAccount" function in the MembershipRebootService to do this and I can see the CustomUser EntityFramework proxy class in the debugger and it's associated properties but not access them?
Hi,
I have a requirement to create an audit trail of all actions that modify the userAccount.
Our initial solution was to add a trigger to the UserAccount table so that we could see a history of what was changing. This was good, however we need to know which MR User is making the change in addition to which DB User is making the change.
I know you can write event handlers for MR, is there a way to write 1 global event handler that will insert into an audit Trail table for all events that happen in MR (Eg Change Password, Login, Verified, Closed, etc)?
If I add to App.Config:
<appSettings> </appSettings>
The application stop working with error:
{"Exception has been thrown by the target of an invocation."}
So :/ I wonder if it's possible to somehow change the 'RequreAccountVerification' property of the active membershiprebootconfiguration based on the 'idp' doing the actual authentication.
What I mean by this is I would ideally like my local users to require an email address that is verified, but if they've authenticated from, lets say, twitter I'm less bothered. (Similar to #20 but for handling the case where an IdP cannot provide an e-mail) Is this possible/reasonable or should I effectively create my own UserService that lets me change that requirement dynamically ?
I am trying to implement MR to send out an email per the documentation over here and have added the following to my app.config
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="c:\temp\maildrop\" />
</smtp>
</mailSettings>
</system.net>
And in my CustomConfig per the this sample project I have added the following....
public class CustomConfig : MembershipRebootConfiguration<CustomUser>
{
public static readonly CustomConfig Config;
static CustomConfig()
{
Config = new CustomConfig();
Config.PasswordHashingIterationCount = 10000;
Config.RequireAccountVerification = false;
Config.EmailIsUsername = true;
var em = new EmailMessageFormatter<CustomUser>(new RelativePathApplicationInformation()
{
ApplicationName = "Test",
EmailSignature = "Test Signature",
RelativeCancelVerificationUrl = "UserAccount/Register/Cancel/",
RelativeConfirmChangeEmailUrl = "UserAccount/ChangeEmail/Confirm/",
RelativeConfirmPasswordResetUrl = "UserAccount/PasswordReset/Confirm/",
RelativeLoginUrl = "UserAccount/Login",
});
Config.AddEventHandler(new EmailAccountEventsHandler<CustomUser>(em));
}
}
Yet when I try a simple method such as SendTwoFactorAuthenticationCode no email shows up in the directory I specified. Any tips on what I am missing and what approach I need to take....
I change Startup.cs with:
app.Map("/admin", adminApp =>
{
var factory = new IdentityManagerServiceFactory();
factory.Configure(connectionString);
adminApp.UseIdentityManager(new IdentityManagerOptions
{
Factory = factory
});
});
// --- Start custom code ---
app.Map("/register", builder => builder.Run(context =>
{
var qs = context.Request.QueryString.Value;
var user = parseUserName(qs);
var pass = parseEmail(qs);
// ?? missing code
var task = context.Response.WriteAsync("User Added");
return task;
}));
// --- end code ----
How can I access functions for adding user to database in missing code part?
For example calling:
https://localhost:44333/core/register?user=jernej&[email protected]&pass=mypass
I've already discussed with @leastprivilege about this in this issue.
Because it came out this is a Thinktecture.IdentityServer.v3.MembershipReboot
problem, I'm reporting it here.
I also thought to make a pull request, but it doesn't worth it because is just a simple fix of one line (as far as I can see, at least).
Specifically, as @leastprivilege pointed out, the problem seems to be in the GetProfileDataAsync
function (MembershipRebootUserService.cs: row 55). It should manage the case in which an empty list is passed as parameter for requestedClaimTypes
. This would add the support for the new property IncludeAllClaimsForUser
of IdentityServer.v3 scopes.
Thanks in advance
We have just implemented an API that uses the Resource Owner Flow. As part of testing, we discovered that the retrieval of the AccessToken is quite slow compared to the Client Credentials Flow. About 4-5s Vs 0.5s.
I understand that it will be longer for Resource Owner because it needs to make a few DB calls.
I had a look through the logs, and it appears as though the longest part of the login is the call to Verify Password.
2016-02-15 10:56:15,128 [21] INFO Sema.IdentityServer.MembershipReboot - [UserAccountService.VerifyPassword] called for accountID: ae790c39-c351-4360-a14b-608919f30100
2016-02-15 10:56:19,910 [21] DEBUG Sema.IdentityServer.MembershipReboot - [UserAccountService.VerifyPassword] success
The call to VerifyPassword seems to take about 4.5 seconds.
the above times are from my DEV environment. Test is about 3-4 seconds, and PROD is 1-2 seconds. I haven't checked UAT.
Is VerifyPassword likely to be slower because of the Database hits or the hashing of the password? I'm just wondering how we can speed this up if possible.
when i add identityserver3.membershipreboot package in a aspnet 5 application, i am not able to access the namespace identityserver3.membershipreboot, i only get identityserver3.core. So do i manually include the class MembershipRebootUserService in order to use it?
I am trying to setup an application that uses MRB with IdentityServer3 with custom UserAccount details.....ohhh and I have thrown Autofac into the mix for DI
I am trying to use the examples from both IdentityServer & MRB to get what I want working but not having much joy.
To better explain I thought I might do a small code dump
I have a CustomUser model
public class CustomUserAccount : RelationalUserAccount
{
// make sure the custom properties are all virtual
public virtual int Age { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
My Controller
private readonly UserAccountService<CustomUserAccount> _userAccountService;
private readonly AuthenticationService<CustomUserAccount> _authService;
public UserAccountController(UserAccountService<CustomUserAccount> userAccountService,AuthenticationService<CustomUserAccount> authSvc)
{
_userAccountService = userAccountService;
_authService = authSvc;
}
I saw that I needed to create a custom database class which looks like
public class MigrationsContextFactory : IDbContextFactory<CustomDatabase>
{
public CustomDatabase Create()
{
return new CustomDatabase("MembershipDb");
}
}
public class CustomDatabase : MembershipRebootDbContext<CustomUserAccount, CustomGroup>
{
public CustomDatabase(string name):base(name)
{
}
}
I am using autofac in my project so I have tried to configure multiple ways within my startup.cs
private static void BuildAutofacContainer(IAppBuilder app, string authType)
{
var builder = new ContainerBuilder();
var config = CreateMembershipRebootConfiguration(app);
builder.RegisterInstance(config).As<MembershipRebootConfiguration>();
builder.RegisterType<DefaultMembershipRebootDatabase>()
.InstancePerLifetimeScope();
builder.RegisterType<DefaultUserAccountRepository>()
.As<IUserAccountRepository>()
.As<IUserAccountRepository<RelationalUserAccount>>()
.As<IUserAccountQuery>()
.As<IUserAccountQuery<BrockAllen.MembershipReboot.Relational.RelationalUserAccount>>()
.InstancePerLifetimeScope();
builder.RegisterType<DefaultUserAccountRepository>()
.As<IUserAccountRepository>()
.InstancePerLifetimeScope();
//My registrations
builder.RegisterType<UserAccountService<CustomUserAccount>>().InstancePerLifetimeScope();
builder.RegisterType<AuthenticationService<CustomUserAccount>>().InstancePerLifetimeScope();
//tried these but dont work
//builder.RegisterType<CustomUserService>().As<IUserService>().InstancePerLifetimeScope();
//builder.RegisterType<CustomUserRepository>().As<IUserAccountRepository<CustomUserAccount>>()
// .InstancePerLifetimeScope();
//builder.RegisterType<CustomUserAccount>()
// .As<CustomUserRepository>()
// .InstancePerRequest();doesnt work
//builder.RegisterInstance(config)
// .As<MembershipRebootConfiguration<CustomUserAccount>>();
//end
builder.RegisterType<CustomUserRepository>()
.As<IUserAccountRepository<CustomUserAccount>>()
.InstancePerRequest();
builder.RegisterType<CustomDatabase>()
.AsSelf()
.InstancePerRequest();
builder.RegisterType<CustomUserRepository>()
.As<IUserAccountQuery>()
.InstancePerRequest();
builder.RegisterType<UserAccountService>().OnActivating(e =>
{
var owin = e.Context.Resolve<IOwinContext>();
var debugging = false;
#if DEBUG
debugging = true;
#endif
e.Instance.ConfigureTwoFactorAuthenticationCookies(owin.Environment, debugging);
})
.AsSelf()
.InstancePerLifetimeScope();
builder.RegisterType<UserAccountService<RelationalUserAccount>>().OnActivating(e =>
{
var owin = e.Context.Resolve<IOwinContext>();
var debugging = false;
#if DEBUG
debugging = true;
#endif
e.Instance.ConfigureTwoFactorAuthenticationCookies(owin.Environment, debugging);
})
.AsSelf()
.InstancePerLifetimeScope();
builder.Register(ctx =>
{
var owin = ctx.Resolve<IOwinContext>();
return new OwinAuthenticationService(authType, ctx.Resolve<UserAccountService>(), owin.Environment);
})
.As<AuthenticationService>()
.InstancePerLifetimeScope();
builder.Register(ctx => HttpContext.Current.GetOwinContext()).As<IOwinContext>();
builder.RegisterControllers(typeof(Startup).Assembly);
var container = builder.Build();
System.Web.Mvc.DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
What am I missing with my setup? I get an error of
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'NS.Account.MembershipReboot.CustomDatabase' can be invoked with the available services and parameters:
Cannot resolve parameter 'System.String name' of constructor 'Void .ctor(System.String)'.
Any suggestions on whats wrong with how I have set things up would be hugely appreciated
Hi,
I'm trying to pass a dynamic connection string but I'm getting an error. Below are the codes:
Connection String:
Factory:
var repo = new DefaultUserAccountRepository(CreateMembershipRebootConnectionString());
public static string CreateMembershipRebootConnectionString()
{
var connString = ConfigurationManager.ConnectionStrings["MembershipReboot"].ToString();
if (HttpContext.Current.Request.UrlReferrer != null)
{
Uri url = HttpContext.Current.Request.UrlReferrer;
if (url.HostNameType == UriHostNameType.Dns)
{
string host = url.Host;
String[] subDomains = host.Split('.');
return String.Format(connString, subDomains[0] + "MembershipReboot");
}
}
return String.Format(connString, "MembershipReboot");
}
The above codes work with Thinktecture.IdentityServer.Core.EntityFramework and BrockAllen.MembershipReboot
Below are the error message and stack trace:
Message: "An error has occurred.",
ExceptionMessage: "An error occurred when trying to create a controller of type 'AuthorizeEndpointController'. Make sure that the controller has a parameterless public constructor.",
ExceptionType: "System.InvalidOperationException",
StackTrace: " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0 at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0 at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext() in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Extensions\ScopeExtensions.cs:line 0",
InnerException: {
Message: "An error has occurred.",
ExceptionMessage: "An exception was thrown while executing a resolve operation. See the InnerException for details. ---> A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 50 - Local Database Runtime error occurred. The specified LocalDB instance does not exist. ) (See inner exception for details.)",
ExceptionType: "Autofac.Core.DependencyResolutionException",
StackTrace: " at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable1 parameters) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0 at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable
1 parameters) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0 at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable1 parameters, Object& instance) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0 at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable
1 parameters) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0 at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType, IEnumerable1 parameters) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0 at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0 at Thinktecture.IdentityServer.Core.Hosting.AutofacScope.GetService(Type serviceType) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 25 at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func
1& activator) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0 at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) in c:\etc\Dropbox\source\Thinktecture\Thinktecture.IdentityServer.v3\Core\source\Core\Hosting\AutofacScope.cs:line 0",
InnerException: {
Message: "An error has occurred.",
ExceptionMessage: "A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 50 - Local Database Runtime error occurred. The specified LocalDB instance does not exist. )",
Thank you,
Hello,
Today i was configuring ADFS, and got a problem with the way MembershipRebootUserService.ProcessNewExternalAccountAsync is implemented.
When Membershipreboot had the option requireAccountVerification="true" after a sucessfull authentication the user is not created with the error :
Warning: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthenticationController]:
19/03/2015 15:59:52 +00:00 -- user service returned error message: Email is required
The reason of this is that even though the claim is provided, the method ProcessNewExternalAccountAsync is not considering it:
user = userAccountService.CreateAccount(
tenant,
Guid.NewGuid().ToString("N"),
null, null,
null, null,
user);
I fixed it by creating a custom UserService... Is this the intention?
Probably it should be:
user = userAccountService.CreateAccount(
tenant,
Guid.NewGuid().ToString("N"),
null, ClaimHelper.GetValue(claims, Constants.ClaimTypes.Email),
null, null,
user);
Thanks,
Leandro
When I use ADFS as an external provider and configure Membership Reboot as the user service in IdentityServer, I get an error (Log is below) that indicates that the CreateAccount method signature shown below is not found. I copied the Samples repository for how to implement MembershipReboot with IdSvr3. The only thing that is different is that I am using ADFS as an AuthenticationOption. I log in with my credentials in the ADFS provider and am redirected back to IdSvr3 (getting the error "There was an unexpected error"). Any ideas?
w3wp.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthenticationController]: 8/5/2015 5:38:08 PM +00:00 -- Callback invoked from external identity provider
w3wp.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.AuthenticationController]: 8/5/2015 5:38:08 PM +00:00 -- external user provider: adfs, provider ID: n1QfLgGMj2CqYoU2C_gzhTFm4n6sZWouTjKjxkUGjX4
w3wp.exe Error: 0 : [Thinktecture.IdentityServer.Core.Configuration.Hosting.LogProviderExceptionLogger]: 8/5/2015 5:38:08 PM +00:00 -- Unhandled exception
System.MissingMethodException: Method not found: 'System.__Canon BrockAllen.MembershipReboot.UserAccountService1.CreateAccount(System.String, System.String, System.String, System.String, System.Nullable
1<System.Guid>, System.Nullable1<System.DateTime>, System.__Canon)'. at Thinktecture.IdentityServer.MembershipReboot.MembershipRebootUserService
1.d__21.MoveNext()
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.Start[TStateMachine](TStateMachine& stateMachine) at Thinktecture.IdentityServer.MembershipReboot.MembershipRebootUserService
1.ProcessNewExternalAccountAsync(String tenant, String provider, String providerId, IEnumerable1 claims) at Thinktecture.IdentityServer.MembershipReboot.MembershipRebootUserService
1.d__1c.MoveNext()
How I can host this in IIS
I also post the same question in Thinktecture.IdentityServer3.Samples
IdentityServer/IdentityServer3.Samples#83
From here: IdentityServer/IdentityServer3#1108
I am trying to unit test some service endpoints that utilize MembershipReboot to create users. I have created an interface to go over UserAccountService so that I can mock the calls to MR to send back the appropriate stuff. Below is what I have setup for CustomUser, CustomUserAccountService, and CustomUserRepository:
public class CustomUser : RelationalUserAccount
{
[Display(Name = "First Name")]
public virtual string FirstName { get; set; }
[Display(Name = "Last Name")]
public virtual string LastName { get; set; }
}
public class CustomUserAccountService : UserAccountService<CustomUser>, ICustomUserAccountService<CustomUser>
{
public CustomUserAccountService(CustomConfig config, CustomUserRepository repo)
: base(config, repo)
{
}
}
public class CustomUserRepository : DbContextUserAccountRepository<CustomDatabase, CustomUser>, ICustomUserRepository
{
public CustomUserRepository(CustomDatabase ctx)
: base(ctx)
{
}
}
When I first boot up I get a ReflectionTypeLoadException within ScopeRequirementMiddleware.cs. If I continue past this exception I end up getting a TypeLoadException stating that CustomUserAccountService does not implement the method 'GetValidationMessage'.
I am a bit confused on why this does not work, the interface is just a wrapper and the parent class UserAccountService actually implements the GetValidationMessage so why is it even looking in CustomUserAccountService?
Hi,
I've come across an issue when implementing authentication with MembershipReboot users that go through a two-step login. They will not be marked as verified by my UserService
until they have completed login with a 2fa-code, and I use MembershipReboot's 2fa-feature for this. Until they successfully authenticate, their UserAccount
is marked as IsAccountVerified=false
and will be deleted by a continually-running cleanup-task after a while.
Now, if you call the /connect/userinfo
endpoint with an access_token
belonging to a user with an unverified account, should it return claims and 200 OK? The OpenID-spec says:
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User.
So just wondering if the IsActiveAsync
method in MembershipRebootUserService
should be changed to be stricter and check the IsAccountVerified
property as well.
ctx.IsActive = acct != null && !acct.IsAccountClosed && acct.IsLoginAllowed;
to
ctx.IsActive = acct != null && !acct.IsAccountClosed && acct.IsLoginAllowed && acct.IsAccountVerified;
This will cause the ValidateAccessTokenAsync
called from the GetUserInfo
of UserInfoEndpointController
in IdentityServer to return invalid_token
for unverified accounts.
Curious to hear your thoughts on this :)
Hi,
I was able to configure EmailAccountEventsHandler in MR. I am having challenges wiring up AuthenticationAuditEventHandler and NotifyAccountOwnerWhenTooManyFailedLoginAttempts in my OWIN project. Any guidance is much appreciated.
Thank you.
I'm not sure if this is a host configuration issue in this solution or a defect in MembershipReboot, but the host example does not specify a tenant when the GroupService is instantiated. This results in a validation exception when a role is created. It seems like the GroupService(IGroupRepository) constructor can never work and should be deleted as DefaultTenant will always be null (or some other set of validation be put in place for this specific use case).
Why is the namespace Thinktecture.IdentityManager.Host instead of SelfHost?
This same issue exists in the Thinktecture.IdentityServer.v3.AspNetIdentity project.
When using IdentityServer3.MembershipReboot v2.0.0 together with the latest version 2.4.0 of IdentityServer3, the following behaviour can be noticed:
When trying to authenticate, the current MembershipReboot implementation leaks information whether a user account exists or not. This can be determined by the time that passes. When there is no user account for the given user name, the response invalid_grant
is received almost immediately.
When a user account exists for the given user name, the response takes significantly longer.
I have added support for the HMAC-Based One-time Password (HOTP) algorithm specified in RFC 4226 and the Time-based One-time Password (TOTP) algorithm specified in RFC 6238 to enable the use of Microsoft and Google authenticator as 2fa mechanism.
Please assign to me if you want this feature brought back into github.
If you extend your model as in sample: https://github.com/IdentityServer/IdentityServer3.Samples/blob/master/source/MembershipReboot/WebHost/MR/CustomUser.cs#L32
And want e.g. FirstName
to control if a given_name claim
should be added/removed for the account, what is the preferred way of doing that? Was looking into overriding UserAccountService.Update(CustomUser account)
and placing calls to AddClaim
vs RemoveClaim
but that recursively calls it self, so what is the preferred way?
When installing the latest version (2.0.0) on a ASP.NET 5 app, the cs file is never copied to the project.
I am unable to customize the error message from "Account is closed" to "Account is inactive". I tried the code as shown in the screenshot. But still when i tried to login It shows "Account is closed". This message is not even defined in RESX file from Membershipreboot project. Any idea how to resolve this?
Hi,
I'm currently using the following for membership reboot in idsvr3:
public class CustomUser : RelationalUserAccount
{
[Display(Name="First Name")]
public virtual string FirstName { get; set; }
[Display(Name = "Last Name")]
public virtual string LastName { get; set; }
}
In the MR database these are added as fields to the UserAccounts table.
By default, it doesn't look like these are returned as claims by identity server.
Is there a way to get them returned as claims without setting them up as claims, or should they be setup as claims to begin with?
Hi,
I am in the process of updating my Identity Server Membership Reboot factory to bring it in line with your latest sample.Everything is working well except for one of my partial sign in pages.
I register the CustomerUserService for MR like this:
public static void ConfigureCustomUserService(this IdentityServerServiceFactory factory, string connString)
{
factory.UserService = new Registration<IUserService, CustomUserService>();
factory.Register(new Registration<CustomUserAccountService>());
factory.Register(new Registration<CustomConfig>(CustomConfig.Config));
factory.Register(new Registration<CustomUserRepository>());
factory.Register(new Registration<CustomDatabase>(resolver => new CustomDatabase(connString)));
}
I have a Password Reset page that will be presented to the user when they log in and their password has expired. My error is happening when they are saving their new password.
I retrieve the UserAccountService from the Owin context. This sometimes works, but most of the time it returns "The operation cannot be completed because the DbContext has been disposed." Is there something I'm missing?
public static UserAccountService<CustomUser> _userService { get; set; }
static UserAccountService<CustomUser> GetUserAccountService(Controller controller)
{
if (_userService == null)
{
_userService = controller.Request.GetOwinContext().Environment.ResolveDependency<CustomUserAccountService>();
}
return _userService;
}
public ActionResult Index(ChangePasswordInputModel model)
{
var currentUser = GetCurrentUser();
var svc = GetUserAccountService(this);
svc.ChangePassword(currentUser.UserId, model.OldPassword, model.NewPassword);
}
Dear all,
I have setup membershipreboot and configured it to use the email as username.
This scenario does not seem to be supported by the MembershipRebootUserService. Is this correct?
If so will it be supported or should I overwrite the AuthotenticateLocalAsync and perform a conversion trick in there.
Thanks for any help you can provide me with.
Alexandre
I am looking for gui configure for same as in memory come from database.. please help
Out the box and after restoring NuGets pckgs, IdSrv.v3.MB builds and runs as a SelfHost without a problem.
Then in the console I noticed the following 5 warnings...
SelfHost.vshost.exe Warning: Thinktecture.IdentityServer.Core.Configuration.IdentityServerServiceFactory]:
While the user is redirected to the /authorize endpoint the following error is thrown in the console:
{{model.username}} is displayed next to the page heading "Thicktecture IdentityServer v3 -" and as soon as "Log Out" or "Login as different user" is clicked, a 404 page not found error is displayed.
Your assistance in this regard would be much appreciated.
I saw that tenants are now supported through the login_hint parameter (#39, #347, #348) and I'm able to successfully pass the tenant property to the server. However the default MembershipRebootUserService doesn't support it. Might I suggest the following minor change to the AuthenticateLocalAsync:
var tenant = string.IsNullOrWhiteSpace(message.Tenant) ? userAccountService.Configuration.DefaultTenant : message.Tenant;
if (userAccountService.Authenticate(tenant, username, password, out account))
The technique may have to be carried over to some of the other methods, but I think in principle this would complete the multi-tenant support.
Thoughts?
Please will you describe the use cases for these two methods?
In the sample code the configuration is:
appBuilder.Map("/admin", adminApp =>
{
var factory = new Thinktecture.IdentityManager.Host.MembershipRebootIdentityManagerFactory("MembershipReboot");
adminApp.UseIdentityManager(new Thinktecture.IdentityManager.IdentityManagerConfiguration()
{
IdentityManagerFactory = factory.Create
});
});
However with the version of IdentityManager installed from nuGet this seems out dated. I tried the following but can't seem to get the ManagerOptions correct.
app.Map("/admin", adminApp =>
{
var factory = new Thinktecture.IdentityManager.Host.MembershipRebootIdentityManagerFactory("MembershipReboot");
adminApp.UseIdentityManager(new Thinktecture.IdentityManager.Configuration.IdentityManagerOptions()
{
Factory = factory.Create
});
});
Can you help? I would really like to get Membership Reboot working with my Identity Server v3 from NuGet.
Thanks in advance...
Hi,
I'm only new to IdentityServer, MembershipReboot etc, so I may be missing something fairly obvious.
I have got IdentityManager up an running locally without too much hassle.
However, when I try to run this version of IdSrv3 with MR I get EF errors when I try and point it to the same DB that is being used by IdentityManager.
I did have it working using the MembershipReboot sample code from the IdentityServer.v3 samples. Although, in my efforts to try and get IdentityServer.v3.MembershipReboot working, I haven't been able to get the sample working again..
Any help would be greatly appreciated.
Here are more details on the behaviour I'm getting:
Connection Strings:
IdentityManager
IdentityService
-- Scenario 1 --
Remove Database
Run Identity Manager (creates DB)
Run Thinktecture.IdentityServer.v3.MembershipReboot
Run JS Client Sample - Error: "An exception of type 'System.Data.SqlClient.SqlException' occurred in EntityFramework.dll but was not handled in user code
Additional information: There is already an object named 'Groups' in the database."
At Line 17 SelfHost.MemberhipRebootUserServiceFactory.cs
"var repo = new DefaultUserAccountRepository(connString);"
-- Scenario 2 --
Remove Database
Run Thinktecture.IdentityServer.v3.MembershipReboot
Run JS Client Sample (creates DB, no logins create yet)
Run Identity Manager - Error: "An exception of type 'System.NotSupportedException' occurred in EntityFramework.dll but was not handled in user code
Additional information: Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations."
At Line 26 in CustomDatabase.cs
" public CustomDatabase(string name)
:base(name)
{
}"
I'm struggling to see how this works. The solution doesn't seem to want to build. It can't seem to find some packages. So I just tried adding the project to my identity server v3 and also adding the extra files into my Host project and couldn't get it to build. Am I going about this the wring way? What's the simplest way to add MembershipReboot to my Identity Server?
Hi guys.
I was implementing an external provider when I realized that the new user's claims from the provider (Steam) were being saved against their claims and not against their LinkedAccountClaims.
I've updated my MembershipRebootUserService to instead of passing in the claims to the create new Membership Reboot user, to pass an empty list of claims, then send the list of claims to the AddOrUpdateLinkedAccount function as shown below:
protected virtual async Task<AuthenticateResult> ProcessNewExternalAccountAsync(string tenant, string provider, string providerId, IEnumerable<Claim> claims)
{
var user = await TryGetExistingUserFromExternalProviderClaimsAsync(provider, claims);
if (user == null)
{
user = await InstantiateNewAccountFromExternalProviderAsync(provider, providerId, claims);
var email = claims.GetValue(Constants.ClaimTypes.Email);
user = userAccountService.CreateAccount(
tenant,
Guid.NewGuid().ToString("N"),
null, email,
null, null,
user);
}
// !!CHANGE HERE!! claims will now be added the the linked account's claims table
userAccountService.AddOrUpdateLinkedAccount(user, provider, providerId, claims);
//userAccountService.AddOrUpdateLinkedAccount(user, provider, providerId);
// !!CHANGE HERE!! don't place the external providers claims into the users claims.
//var result = await AccountCreatedFromExternalProviderAsync(user.ID, provider, providerId, claims);
var result = await AccountCreatedFromExternalProviderAsync(user.ID, provider, providerId, new List<Claim>());
if (result != null) return result;
return await SignInFromExternalProviderAsync(user.ID, provider);
}
Is what I've done here ok? Or am I using the LinkedAccountClaims table wrong?
Cheers.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.