Git Product home page Git Product logo

identityserver3.membershipreboot's People

Contributors

brockallen avatar cendter avatar leastprivilege avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

identityserver3.membershipreboot's Issues

UTC offset applied twice to updated_at claim

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.

Claims Being Dropped

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.

Retrieving CustomUser Properties

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?

Capturing All Events in Audit Trail

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)?

appSettings

If I add to App.Config:

  <appSettings>
  </appSettings>

The application stop working with error:
{"Exception has been thrown by the target of an invocation."}

Handling 'RequireAccountVerification' when federating across multiple IdPs

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 ?

Configuring MR for sending emails

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....

Add user - with code

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

IncludeAllClaimsForUser support

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

Performance Query

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.

Setting up MRB with CustomUserDetails and IdentitySever

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

Error in connecting to database using dynamic connection string

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, IEnumerable1 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, 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, 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, Func1& 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,

Problem with MembershipRebootUserService and requireAccountVerification="true" and External Provider

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

Missing Method Exception UserAccountService.CreateAccount for External Provider

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.Nullable1<System.Guid>, System.Nullable1<System.DateTime>, System.__Canon)'. at Thinktecture.IdentityServer.MembershipReboot.MembershipRebootUserService1.d__21.MoveNext()
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.Start[TStateMachine](TStateMachine& stateMachine) at Thinktecture.IdentityServer.MembershipReboot.MembershipRebootUserService1.ProcessNewExternalAccountAsync(String tenant, String provider, String providerId, IEnumerable1 claims) at Thinktecture.IdentityServer.MembershipReboot.MembershipRebootUserService1.d__1c.MoveNext()

ReflectionTypeLoadException in ScopeRequirementMiddleware.cs

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?

Should unverified accounts return their claims when UserInfo is requested?

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 UserServiceuntil they have completed login with a 2fa-code, and I use MembershipReboot's 2fa-feature for this. Until they successfully authenticate, their UserAccountis 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_tokenbelonging 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 IsActiveAsyncmethod in MembershipRebootUserServiceshould 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 ValidateAccessTokenAsynccalled from the GetUserInfoof UserInfoEndpointControllerin IdentityServer to return invalid_tokenfor unverified accounts.

Curious to hear your thoughts on this :)

Configuring MR for Authentication Audit Event Handler

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.

Getting "Tenant is required" validation exception when creating a role even though identity manager is configured to be single tenant.

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).

Potential security issue: Authentication implementation leaks details about existing user accounts

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.

Q: when extending model, also generate claims

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?

Change the error message from "Account is closed" to "Account is inactive"

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?

image

Returning CustomAccount fields as claims

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?

The operation cannot be completed because the DbContext has been disposed.

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);
}

Login with email address

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

Falling back to InMemory and failing to render Login page

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]:

  • AuthorizationCodeStore not configured - falling back to InMemory
  • TokenHandleStore not configured - falling back to InMemory
  • ConsentService not configured - falling back to InMemory
  • RefreshTokenStore not configured - falling back to InMemory
  • ViewService not configured - falling back to EmbeddedAssets

While the user is redirected to the /authorize endpoint the following error is thrown in the console:

  • Failed to render login page

{{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.

Tenants with MembershipRebootUserService

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?

Trouble Registering the Factory.

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...

Is this version compatible with IdentityManager?

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)
{
}"

Building

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?

Adding new user via External Provider - saving their claims

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.