what is the substitute of CreateIdentityAsync method in Asp.Net Core 1.0 RTM? - asp.net-core-1.0

In ASP.Net Core1.0 RTM, I'm trying to create Identity using this method:
userManager.CreateIdentityAsync()
but I get this error:
'UserManager' doesnot contain a definition for 'CreateIdentityAsync'.
What is going wrong?

You can try IUserClaimsPrincipalFactory
ClaimsPrincipal claimsPrincipal = await _claimsPrincipalFactory.CreateAsync(user);
((ClaimsIdentity) claimsPrincipal.Identity).AddClaim(new Claim("user_id", user.Id.ToString()));

I use ClaimsIdentityFactory(). Here is my code:
public async Task<ClaimsIdentity>
GenerateUserIdentityAsync(UserManager<ApplicationUser> manager,
string AuthenticationType)
{
var factory = new ClaimsIdentityFactory<ApplicationUser>();
return await factory.CreateAsync(manager, this, AuthenticationType);
}

Try this: signInManager.SignInAsync(user, false);

Related

No sign-out authentication handler is registered for the scheme 'Identity.TwoFactorUserId'

ASP.NET Core 2.2 web app using code migrated from full fat MVC app.
My AccountController contains this simple code for its Logout route.
await this.SignInManager.SignOutAsync();
return this.RedirectToAction(nameof(Landing.HomeController.Index), "Home");
But this gives.
No sign-out authentication handler is registered for the scheme 'Identity.TwoFactorUserId'.
Pretty confusing given that I've never mentioned 2FA in my code, and Google login is working.
serviceCollection
.AddIdentityCore<MyUser>(identityOptions =>
{
identityOptions.SignIn.RequireConfirmedEmail = false;
})
.AddUserStore<MyUserStore>()
.AddSignInManager<SignInManager<MyUser>>();
serviceCollection.AddAuthentication(IdentityConstants.ApplicationScheme)
.AddCookie(IdentityConstants.ApplicationScheme, options =>
{
options.SlidingExpiration = true;
})
.AddGoogle(googleOptions =>
{
this.Configuration.Bind("OAuth2:Providers:Google", googleOptions);
googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
})
.AddExternalCookie();
As a complement to #Luke's answer:
The reason why SignInManager::SignOutAsync() throws is this method will also sign out the TwoFactorUserIdScheme behind the scenes:
public virtual async Task SignOutAsync()
{
await Context.SignOutAsync(IdentityConstants.ApplicationScheme);
await Context.SignOutAsync(IdentityConstants.ExternalScheme);
await Context.SignOutAsync(IdentityConstants.TwoFactorUserIdScheme);
}
(See source code)
Typically, these tree authentication schemes are registered automatically by AddIdentity<TUser, TRole>():
public static IdentityBuilder AddIdentity<TUser, TRole>(
this IServiceCollection services,
Action<IdentityOptions> setupAction)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
...
.AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>
{
o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
});
... // other services
}
(See source code )
However, you added the Identity services by AddIdentityCore<>() instead of the AddIdentity<>().
Because the AddIdentityCore<>() doesn't register a TwoFactorUserIdScheme scheme (see source code) automatically, there's no associated CookieAuthenticationHandler for TwoFactorUserIdScheme. As a result, it throws.
How to solve
In order to work with SignInManager.SignOutAsync(), according to above description, we need ensure a <scheme>-<handler> map has been registed for TwoFactorUserIdScheme .
So I change your code as below, now it works fine for me:
serviceCollection.AddAuthentication(IdentityConstants.ApplicationScheme)
.AddCookie(IdentityConstants.ApplicationScheme, options =>
{
options.SlidingExpiration = true;
})
.AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>
{
o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
})
.AddGoogle(googleOptions =>
{
this.Configuration.Bind("OAuth2:Providers:Google", googleOptions);
googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
})
.AddExternalCookie();
Also you can create your own SignInManager<MyUser> and override sign out as you need
public class CustomSignInManager : SignInManager<MyUser>
{
public override async Task SignOutAsync()
{
await Context.SignOutAsync(IdentityConstants.ApplicationScheme);
await Context.SignOutAsync(GoogleDefaults.AuthenticationScheme);
}
}
Then change AddSignInManager<SignInManager<MyUser>>() to AddSignInManager<CustomSignInManager>() in your Startup class
serviceCollection
.AddIdentityCore<MyUser>(identityOptions =>
{
identityOptions.SignIn.RequireConfirmedEmail = false;
})
.AddUserStore<MyUserStore>()
.AddSignInManager<CustomSignInManager>();
Do not use the SignOutAsync method on a SignInManager<T> you've injected into the controller. Instead, use the method on the HttpContext which takes a scheme argument. I don't know why.
Below code works for me , use the same AuthenticationScheme that you use while "AddAuthentication" in startup.cs
[HttpGet("signout")]
[AllowAnonymous]
public async Task signout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var prop = new AuthenticationProperties
{
RedirectUri = "/logout-complete"
};
// after signout this will redirect to your provided target
await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme, prop);
}
[HttpGet("logout-complete")]
[AllowAnonymous]
public string logoutComplete()
{
return "logout-complete";
}
I agree with itminus reply, We would get an error because in .net core 3.0 if we use AddIdentityCore<>() instead of AddIdentity<>() we would get an error. But when upgrading to .net 7.0 if we again use AddIdentityCore<>() instead of AddIdentity<>() we would get the same error for Identity.TwoFactorRememberMeScheme as well that I am faced with after upgrading. For SignInManager we require Identity.TwoFactorRememberMeScheme as well otherwise we get an error.
The solution which I applied in mine .net 7.0 project is:
Instead of adding every scheme and handler by yourself, we can just use
services.AddAuthentication().AddIdentityCookies();
This will add all the schemes handlers for you and at the time of signout we need to should use below:
await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
await HttpContext.SignOutAsync(IdentityConstants.TwoFactorUserIdScheme);

.NET Core 2.1 Azure AD B2C Web and API

It is easy to create an Azure AD B2C Web or API App out of the box using VS 2017 15.7.2+.
So I created a solution that has both, but I am trying to get the access token from the Web App and use it to call the API and I cannot find a way.
I tried option 1 (doesn't work):
private async Task<string> GetAccessTokenCacheAsync()
{
string authority = $"{AzureAdOptions.Instance}{AzureAdOptions.ClientId}/{AzureAdOptions.SignUpSignInPolicyId}/";
string clientId = AzureAdOptions.ClientId;
Uri redirectUri = new Uri("https://localhost:12345/");
string resource = targetApplicationID;
AuthenticationContext ac = new AuthenticationContext(authority);
AuthenticationResult result = null;
try
{
result = await ac.AcquireTokenSilentAsync(resource, clientId);
}
catch (AdalException adalException)
{
if (adalException.ErrorCode == AdalError.FailedToAcquireTokenSilently
|| adalException.ErrorCode == AdalError.InteractionRequired)
{
result = await ac.AcquireTokenAsync(resource, clientId, redirectUri,
new PlatformParameters()); //PromptBehavior.Auto
}
}
return result.AccessToken;
}
And I Got:
System.NotImplementedException: 'The method or operation is not implemented.'
I tried option 2 (doesn't work), MSAL (Microsoft.Identity.Client):
private async Task<string> GetAccessTokenCacheAsync() {
string authority = $"{AzureAdOptions.Instance}{AzureAdOptions.ClientId}/{AzureAdOptions.SignUpSignInPolicyId}/";
PublicClientApplication myApp = new PublicClientApplication(AzureAdOptions.ClientId, authority);
AuthenticationResult authenticationResult = await myApp.AcquireTokenAsync(
new[] { $"{ApiScopeUrl}/read", $"{ApiScopeUrl}/write" }
,
myApp.Users.FirstOrDefault()
,
UIBehavior.ForceLogin
,null,null
,authority
).ConfigureAwait(false);
return authenticationResult.AccessToken;
}
And I Got:
System.NotImplementedException: 'The method or operation is not implemented.'
I also tried to adapt the code from Azure samples such as https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi (Framework 4.5.1) or https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore (Core 2.0 and OpenID, no B2C) and fail.
This https://github.com/Azure-Samples/active-directory-b2c-dotnetcore-webapp also mention to implement OnAuthorizationCodeReceived, but Core 2.1 seems to has this implemented with AddAzureADB2C (black-boxed). The documentation on this new library seems to be missing or in progress because I can't find it.
I want to know, how to get the Access Token using built-in features in .NET Core 2.1?
I believe if I know how to implement OnAuthorizationCodeReceived, I will be one step closer to find the answer. Here the code source and ticket that I created relates to this: https://github.com/aspnet/AADIntegration/issues/21

ASP.NET core WEB API with AD FS authentication

I have small RESTful API written in ASP.NET core and I am looking into how to add authentication to it using Active Directory. I have to use our companies server for authentication using AD but I do not see any tutorials of how to do this.
I guess that JWT authentication is not what I am looking for or I might be wrong and misunderstand something. I am total noob in question of authentication.
I know we have solved that in one of the nodejs project of ours and it was not that straight forward. I would appreciate any help in that matter.
As of today, System.DirectoryServices hasn't been implemented in ASP.NET Core yet, but we could use Novell.Directory.Ldap.NETStandard.
You can install the package via NuGet Novell.Directory.Ldap.NETStandard.
Sample code -
using Novell.Directory.Ldap;
namespace YourNamespace
{
public class LdapAuthenticationService : IAuthenticationService
{
public bool ValidateUser(string domainName, string username, string password)
{
string userDn = $"{username}#{domainName}";
try
{
using (var connection = new LdapConnection {SecureSocketLayer = false})
{
connection.Connect(domainName, LdapConnection.DEFAULT_PORT);
connection.Bind(userDn, password);
if (connection.Bound)
return true;
}
}
catch (LdapException ex)
{
// Log exception
}
return false;
}
}
}

owin oauth webapi with a dynamic TokenEndpointPath (request for example)

I refer to post of David Snipp in https://stackoverflow.com/a/29706891/4609861 to kindly ask a little example of his explanation; I am having troubles calling delegate OnMatchEndpoint and the MatchesTokenEndpoint. thx
You can specify the delegates on Options itself in your Startup.cs code. Something along these lines:
OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions()
{
provider = new OAuthAuthorizationServerProvider()
{
OnMatchEndpoint = (context =>
{ // do your stuff
context.MatchesAuthorizationEndpoint();
return Task.FromResult<object>(0);
});
}
}

Can't Resolve a service using AppHostBase.ResolveService<T> API in ServiceStack 4

I'm using ASP.NET MVC 5 and attempting to resolve a few services using the example:
var authService = AppHostBase.Resolve<AuthService>();
authService.RequestContext = System.Web.HttpContext.Current.ToRequestContext();
var response = authService.Authenticate(new Auth
{
UserName = model.UserName,
Password = model.Password,
RememberMe = model.RememberMe
});
or I've also tried:
using (var helloService = AppHostBase.ResolveService<HelloService>())
{
ViewBag.GreetResult = helloService.Get(name).Result;
return View();
}
In the first case I needed the RequestContext injected so I tried that approach and in the second case I was using the example which I understand has the RequestContext automatically injected through Funq.
ResolveService could not be found when I tried the second approach and in the first approach RequestContext is not a valid property. Am I missing something simple or has there been changes to the API?
The documentation does appear to be wrong for this as there is no longer a ResolveService<T> on AppHostBase. It needs to be updated due to changes in the Api.
You can do this in ServiceStack v4 with MVC:
var authService = HostContext.Resolve<AuthService>();
...

Resources