Giter Club home page Giter Club logo

accidentalfish.aspnet.identity.azure's Introduction

AccidentalFish.AspNet.Identity.Azure

This .Net 4.5 assembly is a collection of helpers for the Asp.Net 4.5 identity model that add support for common Azure usage scenarios. Currently included are:

  • Use Azure Active Directory groups as roles in ASP.Net authentication with the Authorize attribute

  • Use Azure Table Storage as a store for identity information with the new OAuth implementation

The assembly is available as a NuGet package named ASP.Net 4.5 Azure Identity Helpers.

In addition to the guidance below further background can be found on my blog Azure From The Trenches.

Using Azure Active Directory Groups as Authorization Roles

Although it’s simple to use Azure Active Directory for authentication (see here) group memberships are not exposed as claims and so if you try and use an authorization attribute with a role (for example [Authorize(Roles=“Operator”)]) you’ll get an UnauthorizedException.

To enable this functionality a claims authentication manager (called GraphRoleClaimsAuthenticationManager) is included in this assembly that, on a successful authentication, uses the Azure AD Graph API to query the directory for group memberships and creates role claims for them.

Before you can use the claims manager however you need to configure the Azure Active Directory your application is using for authentication to support read access of the graph data.

Before commencing with the below it’s worth ensuring that your web site does already authenticate against Azure Active Directory without roles just to be sure that you’ve got the basics configured correctly.

Configuring Your Azure Active Directory

Assuming you’ve already got a website authenticating against an Azure Active Directory then you should see it listed in the Applications tab of your Active Directory in the Azure Management Portal. You can see mine listed below:

Select your application and you’ll be taken to the application configuration page whish should look something like the below:

To configure your app you need to tap the Manage Access button down the bottom. Do that and then select Change the directory access for this app. Then on the next page select Single sign on, read directory data.

Azure will whirr away for a short while changing settings on your AD and when it’s done you need to go to the Configure tab (click configure at the top of the page as shown in the image above). In here you need to create a key that your application can use to authenticate with the Graph API and read AD data.

To do this scroll down to the Keys section and click the drop down and choose whether you want a 1 year or 2 year key. In the screenshot below I’ve picked 1 year.

After you’ve done this click save in the toolbar at the bottom and you’ll see your key.

We’ve just about done in the Azure Management Portal all you need to do before you leave is take note of the Client ID and the Key as shown in the image below (mine are blurred out!).

Configuring Your Application

For the rest of this walkthrough I’m assuming you’re configuring a web site rather than an Azure Web Role but the claims manager uses the Azure Configuration Manager so if you are using a Web Role you can simply put the settings in your .cscfg and .csdef files.

Firstly add the NuGet package to your project which you can do in the Package Manager GUI or in the console:

Install-Package accidentalfish.aspnet.identity.azure

Then you need to edit your web.config file with a couple of app settings. For this you need your Client ID and Key that you noted down earlier.

The RoleClaimIssuer is optional but is the claim issuer you want inserted into the claim, if you leave this out the issuer will be set as DefaultRoleIssuer.

The final step you need to take is to tell the ASP.Net identity model about the claims manager. To do this locate the <system.identitymodel> section of the web.config file and insert the line highlighted below at the bottom just before the closing element:

The line to paste is:

<claimsAuthenticationManager type="AccidentalFish.AspNet.Identity.Azure.GraphRoleClaimsAuthenticationManager, AccidentalFish.AspNet.Identity.Azure"/>

With that you’re done and you can use the groups you’ve configured in the Azure AD as roles with the [Authorize(Roles="...")] attribute.

Using Azure Table Storage as an Identity Store

The new identity model in ASP.Net 4.5 provides a pretty solid seperation between the business logic of identity management and the storage of identity information via a set of interfaces however it only ships with an implementation for Entity Framework (compatible with SQL Server and SQL Database).

The AccidentalFish.AspNet.Identity.Azure assembly contains the necessary implementation of these interfaces against Azure Table Storage however the ASP.Net New Project templates contain code that is needlessly tied to the Entity Framework so there are a few steps you need to take to swap out the Entity Framework implementation.

Web API 2

Firstly add the NuGet package to your project which you can do in the Package Manager GUI or in the console:

Install-Package accidentalfish.aspnet.identity.azure

Now open the Startup.Auth.cs file and make the three changes shown below towards the top of the file:

The above assumes that you have a storage account connection string contained in an app setting called my-connection-string. Change this to get, or construct, the storage account connection string as pertinent to your application.

Now open the AccountController.cs file. This contains references to the Entity Framework identity provider types IdentityUser and IdentityUserLogin and you need to change them to TableUser and TableUserLogin - either do a search and replace or add a pair of aliases to the top and comment out the namespace reference as shown below:

That’s all the changes complete and with the approach taken above the new identity provider will function just like the Entity Framework version creating tables in your storage account when necessary.

MVC 5

Firstly add the NuGet package to your project which you can do in the Package Manager GUI or in the console:

Install-Package accidentalfish.aspnet.identity.azure

You may need to update various NuGet packages, depeding on the MVC template you are starting from. If you get ambiguous reference errors or invalid reference versions, that would be the first thing to try.

Now open the Startup.Auth.cs file and add the block of code shown to the top of the class:

Next, open the IdentityModels.cs file and replace the entire file with the code below (make sure to use your project's namespace instead of the example namespace):

Then, open the AccountController.cs file and replace the constructor with the code below:

Finally, add the table storage connection string to your web.config file. The following entry is appropriate for development:

You will need to remove any using statement that references EntityFramework so that the application can compile and run.

License

Copyright (C) 2013 Accidental Fish Ltd.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

accidentalfish.aspnet.identity.azure's People

Contributors

akimbrel avatar andorbal avatar chrisbartlett avatar jameskeongchen avatar jamesrandall avatar jayvdz avatar tornal 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  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

accidentalfish.aspnet.identity.azure's Issues

UserManager.CreateAsync(user, model.Password) fails

I'm getting the following exception when creating a new user. I've tracked down what might be the issue: in public async Task CreateAsync(T user) user.Email is populated on my ApplicationUser model being passed in (I can see this whilst debugging), but the TableUserStore is casting to TableUser and the Email property on that cast is null, as checked by ``if (!String.IsNullOrWhiteSpace(user.Email))`. There's some issue between the ApplicationUser.Email and TableUser.Email properties being different. This is also causing the Email indexing code to be skipped.

Thanks for the FindByEmailAsync functionality, I need it for checking email uniqueness at registration time.

Stack trace:

The remote server returned an error: (400) Bad Request.

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.Net.WebException: The remote server returned an error: (400) Bad Request.

Source Error: 


Line 168:                throw;
Line 169:            }
Line 170:        }
Line 171:
Line 172:        public async Task UpdateAsync(T user)

Source File: c:\Users\xxx\xxx\AccidentalFish.AspNet.Identity.Azure\TableUserStore.cs    Line: 170 

Stack Trace: 


[WebException: The remote server returned an error: (400) Bad Request.]
   Microsoft.WindowsAzure.Storage.Table.Protocol.TableOperationHttpResponseParsers.TableOperationPreProcess(TableResult result, TableOperation operation, HttpWebResponse resp, Exception ex) +318
   Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndGetResponse(IAsyncResult getResponseResult) +811

[StorageException: The remote server returned an error: (400) Bad Request.]
   Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndExecuteAsync(IAsyncResult result) +258
   Microsoft.WindowsAzure.Storage.Core.Util.<>c__DisplayClass1-1.<CreateCallback>b__0(IAsyncResult ar) +294
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
   System.Runtime.CompilerServices.TaskAwaiter1.GetResult() +49
   AccidentalFish.AspNet.Identity.Azure.<CreateAsync>d__0.MoveNext() in c:\Users\Jay\Dropbox\HotridesMvc3\AccidentalFish.AspNet.Identity.Azure\TableUserStore.cs:170
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
   Microsoft.AspNet.Identity.<CreateAsync>d__0.MoveNext() +2463
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
   Microsoft.AspNet.Identity.<CreateAsync>d__d.MoveNext() +1420
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
   System.Runtime.CompilerServices.TaskAwaiter1.GetResult() +49
   HotridesMvc3.Controllers.<Register>d__a.MoveNext() in c:\Users\Jay\Dropbox\HotridesMvc3\HotridesMvc3\Controllers\AccountController.cs:149
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +144
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +84
   System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +143
   System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult) +23
   System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +112
   System.Web.Mvc.Async.<>c__DisplayClass48.<InvokeActionMethodFilterAsynchronouslyRecursive>b__41() +452
   System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +15
   System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +37
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +241
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
   System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +111
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
   System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +19
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +51
   System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +111
   System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +282

The UTC time represented when the offset is applied must be between year 0 and 10,000. Parameter name: offset

I am getting following exception while creating the user.

I am using the ASP.Net 4.5 Azure Identity Helpers 0.3.0.3

[ArgumentOutOfRangeException: The UTC time represented when the offset is applied must be between year 0 and 10,000.
Parameter name: offset]
System.DateTimeOffset.ValidateDate(DateTime dateTime, TimeSpan offset) +10713799
System.DateTimeOffset..ctor(DateTime dateTime) +85
Microsoft.WindowsAzure.Storage.Table.EntityProperty.get_DateTimeOffsetValue() +213
lambda_method(Closure , Object , OperationContext , IDictionary2 ) +6543 Microsoft.WindowsAzure.Storage.Table.TableEntity.ReadEntity(IDictionary2 properties, OperationContext operationContext) +201
Microsoft.WindowsAzure.Storage.Table.EntityUtilities.ResolveEntityByType(String partitionKey, String rowKey, DateTimeOffset timestamp, IDictionary2 properties, String etag) +199 Microsoft.WindowsAzure.Storage.Table.Protocol.TableOperationHttpResponseParsers.ReadAndResolve(ODataEntry entry, Func6 resolver) +825
Microsoft.WindowsAzure.Storage.Table.Protocol.TableOperationHttpResponseParsers.TableQueryPostProcessGeneric(Stream responseStream, Func6 resolver, HttpWebResponse resp, TableRequestOptions options, OperationContext ctx, String accountName) +1044 Microsoft.WindowsAzure.Storage.Table.<>c__DisplayClass102.b__f(RESTCommand1 cmd, HttpWebResponse resp, OperationContext ctx) +247 Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ProcessEndOfRequest(ExecutionState1 executionState) +222
Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync(RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) +4205

[StorageException: The UTC time represented when the offset is applied must be between year 0 and 10,000.
Parameter name: offset]
Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync(RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext) +7389 Microsoft.WindowsAzure.Storage.Table.TableQuery1.ExecuteQuerySegmentedInternal(TableContinuationToken token, CloudTableClient client, CloudTable table, TableRequestOptions requestOptions, OperationContext operationContext) +435
Microsoft.WindowsAzure.Storage.Table.<>c__DisplayClass7.b__6(IContinuationToken continuationToken) +141
Microsoft.WindowsAzure.Storage.Core.Util.d__01.MoveNext() +123 System.Linq.Enumerable.SingleOrDefault(IEnumerable1 source) +4098209
AccidentalFish.AspNet.Identity.Azure.<>c__DisplayClass24.b__23() +585
System.Threading.Tasks.Task1.InnerInvoke() +60 System.Threading.Tasks.Task.Execute() +45 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter1.GetResult() +24
Microsoft.AspNet.Identity.d__4.MoveNext() +1116
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21
Microsoft.AspNet.Identity.d__0.MoveNext() +468
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
System.Runtime.CompilerServices.ConfiguredTaskAwaiter.GetResult() +24
Microsoft.AspNet.Identity.d__0.MoveNext() +846
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
System.Runtime.CompilerServices.ConfiguredTaskAwaiter.GetResult() +24
Microsoft.AspNet.Identity.d__d.MoveNext() +1113
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
System.Runtime.CompilerServices.TaskAwaiter1.GetResult() +24 GeniusPods.SharePoint.ZeroTo365Web.Controllers.<Register>d__9.MoveNext() in c:\GeniusPods\GPTFS-SourceCode\0To365\Development\Sprint 1\0To365Web\0To365Web\Controllers\AccountController.cs:92 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21 System.Threading.Tasks.TaskHelpersExtensions.ThrowIfFaulted(Task task) +61 System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +114 System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult) +66 System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +47
System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +136 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +49 System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +117 System.Web.Mvc.Async.<>c__DisplayClass48.<InvokeActionMethodFilterAsynchronouslyRecursive>b__41() +323 System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +44 System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +47
System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +136 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +50 System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +72 System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +185 System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +42
System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +133 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +40 System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +34 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +70
System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +139 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +44 System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +39 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +62
System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +139 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59 System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +39 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +39 System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +39 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +70
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +40
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +129

Unable to cast object of type 'AccidentalFish.AspNet.Identity.Azure.TableUserEmailIndex' to type 'Domain.Entities.ApplicationUser'

Hi I found this error while confirming the code for password recovery or email confirmation.
The error occur when following the callback URL generated by these methods:

var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);

var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);

The user id is an email in both cases.
Thanks

Calling RemoveFromRoleAsync from UserManager throws exception

Calling RemoveFromRoleAsync method from the UserManger class throws an ArgumentNull exception with the following message:

Delete requires an ETag (which may be the '*' wildcard).

There's no overload for RemoveFromRoleAsync that allows sending an ETag.

Full example:

var userManager = Startup.UserManagerFactory();
// Exception thrown here:
await userManager.RemoveFromRoleAsync(userId, role);

Web API 2 - Cannot implicitly convert type 'Project.Models.ApplicationUser' to 'AccidentalFish.AspNet.Identity.Azure.TableUser'

I followed your "Web API 2" instructions exactly, and I'm getting an error after changing "IdentityUser" to "TableUser" in AccountController.cs in the "GetManageInfo" method. The error is: "Cannot implicitly convert type 'Project.Models.ApplicationUser' to 'AccidentalFish.AspNet.Identity.Azure.TableUser'".

The line of code it's complaining about is: TableUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId());

Any ideas? Thanks.

Build breaks with Windows Azure Storage 3.1.0.0

Hi guys, I built a new MVC project and couldn't get the Nuget package to work when following the MVC guide again (I've already done it once before) whilst experiencing a "The type 'xxxx.Models.ApplicationUser' must be convertible to 'Microsoft.AspNet.Identity.IUser' in order to use it as a parameter 'TUser' in the generic class 'Microsoft.AspNetIdentity.UserManager' error on the Startup.Auth.cs file.

I thought this might have been an incompatibility with the new AspNet Identity Nuget packages released today, so downloaded the project from here, built it okay, then one by one updated the Nuget packages - the Windows Azure Storage 3.1.0.0 update broke the build. I don't know if this is the only issue, but it's certainly one.

TableUserStore.cs appears to be querying the claims table for roles

GetRolesAsync is querying the claims table for TableUserRole items. I was trying to wire up a way to get Role Claims (ClaimTypes.Role) into my ClaimsPrincipal in a MVC app so that User.IsInRole calls would flow through and get roles from the TableUserRole area. I found that using AddToRoleAsync and then calling GetRolesAsync didn't work...it was just querying the wrong azure table. The conflict I have is whether these roles should be stored as actual claims and populated using GetClaimsAsync instead. Either way...there is a small bug in there.

Announcing RTM of ASP.NET Identity 2.0.0

Hi James,

Have you got any plans to update / implement the new interfaces in ASP.NET Identity 2.0.0 to support password reset etc.

Let me know if you'd like help.

Regards,

James.

IsInRoleAsync not working

Line 704 needs the role to be encoded:

TableOperation operation = TableOperation.Retrieve(user.Id, role.Base64Encode());

Any way to store multiple logins per user?

If you create one login, using say Google, there doesn't seem to be a way to associate another login with the user, say for Facebook. Looking at the logins table this seems to be because there's no row key to uniquely identify rows for the user id (partition key). Is this so or am I just using it wrong?

A lot of sites using social logins miss this scenario out, where a user logs in using one provider initially and then with a different provider the next time and either you end up with a new account or as in this case, an exception is thrown.

TableUser is not scalable

The TableUser table entity is using the same values for its parition key and row key as shown in the SetPartitionAndRowKey below
public void SetPartitionAndRowKey()
{
PartitionKey = Id;
RowKey = Id;
}

Having a unique PartitionKey is not a best practice for AzureTable and won't scale. It would be better to use a partition key built from a sharding method from the username for example.

No IUserTokenProvider is registered.

I can't be certain this issue is to do with the provider so please accept my apologies if it's just me being a dumbass... I'm getting the following exception:

System.NotSupportedException: No IUserTokenProvider is registered.

When I implement email confirmation during user registration:
var token = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);

If it's not me being a dumbass, could this be an unsupported feature of the new stuff mentioned in this issue?:
#9

MVC Integration?

Thanks for the project! The readme has instructions on how to integrate Identity on ATS with an API project but not an MVC one and I'm struggling to work it out for myself as there seems to be completely different implementations between them insofar as how Identity is initialised. Is there any chance there's an example online somewhere?

When updating a user the userEmailIndex and userIndexItens tables are not updated with the new email base64 hash

Hi,

I started using this code in a project where we need to allow the users to change it's email and the username since both properties contain the user email.

Howerver, after implementing the UpdateAsync method I confirmed that even though the table users was updated correctly, the tables userMailIndex and userIndexItems weren't. This caused a major bug on the authentication where the user could only authenticate using the old email (since it's base64 hash was still on the index tables) and the new email would not work.

I coded a workaround for this problem for my project where I manually update the index tables when the user changes it's email, but it would be nice if this code were implemented on the Update and UpdateAsync methods so it works properly to update all the User properties.

Cannot sign user in - ApplicationUser is the wrong one

Is anyone else having problems unable to log users in?

FindByIdAsync(string userId) is having the wrong userId passed in. The userId being passed in is the ApplicationUser.Id value, which isn't the same as TableUser.PartitionKey. It seems to be a new guid every time.

My code hasn't changed, but there was a Nuget update for the Microsoft.AspNet.Identity.* packages in May. I wonder if this has introduced some breaking changes.

Multiple applications

Is it possible to store the profiles for multiple applications in the same tables?

Role authorization is always false even though user is member of Azure AD group

Authenticated user is a member of a group and the group claims include the object ID of this group but [Authorize(Roles = "GroupName")] is returning not authorized and ClaimsPrincipal.Current.IsInRole("GroupName") is returning false.

I don't see any exceptions, if there are configuration, compatibility or other errors in internal to GraphRoleClaimsAuthenticationManager are they logged anywhere?

Submitting a patch?

What's the best way to submit a patch? I've been having problems with the FindByEmailAsync method and an invalid cast exception. I've fixed the issue in the patch so would like to submit it for review. I'm new to Git so apologies if how you do this is meant to be obvious.

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.