Git Product home page Git Product logo

active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore's Introduction

active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore's People

Contributors

acomsmpbot avatar aprilspeight avatar ashrafalam avatar bgavrilms avatar camsoper avatar cmatskas avatar danieldobalian avatar dstrockis avatar gsacavdm avatar jmprieur avatar k-rush avatar priyamohanram avatar shlgug avatar supernova-eng avatar ysrmmz avatar yujhongmicrosoft 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  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  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  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

active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore's Issues

Breaks When Upgrading to .NET Core 2.1.1 and removing custom extensions

This example uses some extension methods defined in AzureAdServiceCollectionExtensions. That [are rather hacky] and made available in Microsoft.AspNetCore.Authentication.AzureAD.UI. However, when I use the same extension method in Microsoft.AspNetCore.Authentication.AzureAD.UI I get the following error:

InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found.
Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)
Microsoft.AspNetCore.Mvc.ChallengeResult.ExecuteResultAsync(ActionContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAlwaysRunResultFilters()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

I tried getting it to work by following the example provided here:

https://github.com/aspnet/AspNetCore/tree/master/src/Azure/AzureAD/samples/AzureADSample

This uses the following code to AddAuthentication:

services.AddAuthentication(AzureADDefaults.AuthenticationScheme) .AddAzureAD(options => Configuration.GetSection("AzureAD").Bind(options));

However, I get the following error:

AADSTS50011: The reply url specified in the request does not match the reply urls configured for the application: '{TodoListService Application Id}'.

The above error doesn't make much sense to me as the TodoListService Application is configured with "https://localhost:44351" Redirect URI (reply URL).

Using this approach gives me the following error again:

InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found.

When I change the sample to:

services.AddAuthentication(AzureADDefaults.AuthenticationScheme) .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));

I get the following error:

This differs from this example which currently does this:

services.AddAuthentication(sharedOptions => { sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddAzureAdBearer(options => Configuration.Bind("AzureAd", options));

However, this current example uses an internal version of the AdAzureAdBearer token (notice the lowercase 'd' in 'Ad'. Whereas the seemingly official version of the extension method uses AdAzureAD()

Issue on SelectPermissions

When creating the applications through the new portal, everything went smoothly up until the last step. After hitting "Select an API" I was not able to find the API that I had created, despite typing in the full name of the app and searching.

I was able to get around it by deleting what I had created, making them in the old manage.windowsazure.com portal, and then returning to the new one to complete the permissions assignment. When I did this, I was able to find the applications to apply permissions.

Hope that helps!

Failed to acquire token silently as no token was found in the cache. Call method AcquireToken

Using the exact code found in the sample I'm getting the following error when calling a resource on behalf of the user calling the API after an hour: "Failed to acquire token silently as no token was found in the cache. Call method AcquireToken".

It works for an hour but when it comes to refreshing the token it fails. I'm trying to access an azure analysis services cube through an API request.

How I'm getting the OBO token:

        public static async Task<string> AcquireOnBehalfOfToken(
            string resourceId,
            string userObjectId,
            ISession session)
        {
            AuthenticationContext authContext = new AuthenticationContext(AzureAdOptions.Settings.Authority, new NaiveSessionCache(userObjectId, session));
            ClientCredential credential = new ClientCredential(AzureAdOptions.Settings.ClientId, AzureAdOptions.Settings.ClientSecret);
            var result = await authContext.AcquireTokenSilentAsync(resourceId, credential, new UserIdentifier(userObjectId, UserIdentifierType.UniqueId));
            var onBehalfOfToken = result.AccessToken;

            return onBehalfOfToken;
        }

My Startup.cs:

    public class Startup
    {
        public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            
            app.UseStaticFiles();

            app.UseSession(); // Needs to be app.UseAuthentication() and app.UseMvc() otherwise you will get an exception "Session has not been configured for this application or request."
            app.UseAuthentication();
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(sharedOptions =>
                {
                    sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                })
                .AddAzureAd(options =>
                {
                    Configuration.Bind("AzureAd", options);
                    AzureAdOptions.Settings = options;
                })
                .AddCookie();
            services.AddSession();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddSessionStateTempDataProvider();
        }
    }

Azure-Samples/active-directory-dotnet-webapi-onbehalfof#25

Small issue

Small issue when adding items to the todolist that wouldn't let me view the items added. Line 56 and 57 of TodoController.cs contain references to the response element that can't be found due to the name being capitalized. The elements need to be "title" and "owner" lowercase instead of "Title" and "Owner".

HTTP 404 error after trying to sign into the "Todo List"

I got an HTTP 404 error after trying to sign into the "Todo List". As you can see in this screenshot, there is a "here" link, and I am signed into my work or school account (my email address is at the top right). (I am not sure why I was not authenticated into the app in the first place when I already logged in.) I clicked the "here" link and ran into the 404 error.

I am using Visual Studio Community 2017 (Version 15.2 (26430.16) Release).

The following is my TodoListService.csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.0</TargetFramework>
    <PreserveCompilationContext>true</PreserveCompilationContext>
    <AssemblyName>TodoListService</AssemblyName>
    <OutputType>Exe</OutputType>
    <PackageId>TodoListService</PackageId>
    <RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
    <PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;dnxcore50;portable-net45+win8</PackageTargetFallback>
  </PropertyGroup>

  <ItemGroup>
    <None Update="Views\**\*">
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </None>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.2" />
  </ItemGroup>

  <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <Exec Command="npm install" />
    <Exec Command="bower install" />
    <Exec Command="gulp clean" />
    <Exec Command="gulp min" />
  </Target>

</Project>

Here is my WebApp-WebAPI-OpenIdConnect-DotNet.csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.0</TargetFramework>
    <PreserveCompilationContext>true</PreserveCompilationContext>
    <AssemblyName>WebApp-WebAPI-OpenIdConnect-DotNet</AssemblyName>
    <OutputType>Exe</OutputType>
    <PackageId>WebApp-WebAPI-OpenIdConnect-DotNet</PackageId>
    <RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
    <PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;dnxcore50;portable-net45+win8</PackageTargetFallback>
  </PropertyGroup>

  <ItemGroup>
    <None Update="wwwroot\**\*;Views\**\*">
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </None>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.TagHelpers" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
    <PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.14.2" />
    <PackageReference Include="Microsoft.AspNetCore.Session" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.2" />
    <PackageReference Include="System.Private.DataContractSerialization" Version="4.3.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.2" />
  </ItemGroup>

  <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <Exec Command="npm install" />
    <Exec Command="bower install" />
    <Exec Command="gulp clean" />
    <Exec Command="gulp min" />
  </Target>

</Project>

Also, I addressed the problem of the "HandleCodeRedemption" function call with empty arguments by adding the appropriate arguments:

private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
	// Acquire a Token for the Graph API and cache it using ADAL.  In the TodoListController, we'll use the cache to acquire a token to the Todo List API
	string userObjectId = (context.Ticket.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value;
	ClientCredential clientCred = new ClientCredential(ClientId, ClientSecret);
	AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectId, context.HttpContext.Session));
	AuthenticationResult authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
		context.ProtocolMessage.Code, new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]), clientCred, GraphResourceId);

	// Notify the OIDC middleware that we already took care of code redemption.
	context.HandleCodeRedemption(authResult.AccessToken, authResult.IdToken);
}

Any assistance would be most appreciated.

possible bug in sample

With the code as is, it is throwing an exception in OnAuthorizationCodeReceived, specifically the notification.RedirectUri is empty.

The code looks odd, since it gets an authResult, but doesn't do anything with it, but mentions it should be caching it for TodoList API?

User impersonation sample

Would it be possible to provide a sample on how to implement user impersonation which supports on behalf of authentication? I'd like to implement it in a development environment. I want downstream APIs like the Graph API or other services like Azure Analysis Services to use the impersonated user too.

failed_to_acquire_token_silently in TodoController.cs

We've tried to set up this project a few times to run the sample but we consistently get a failed_to_acquire_token_silently exception on line 34 of TodoController.cs. There are times this request will work the first time, but subsequent requests always fail and end up being redirected to an AccessDenied action in the Account controller which doesn't exist, resulting in a 404.

Any ideas what might be going on?

This sample will not build with ASP.Net 5/MVC 6 Beta 8

Could someone please update this sample to the latest beta of ASP.Net 5/MVC 6. Currently the latest release is beta 8. There appears to be significant differences between beta 3 and beta 8. For instance, Microsoft.AspNet.Security appears to be no longer supported. It looks like you need to be referencing Microsoft.AspNet.Authentication namespaces instead. The problem is these namespaces have some significant differences, so it's difficult to figure out what the necessary changes should be. It's really surprising that these samples have not been updated.

Invalid access token received.

While authenticating against Azure AD , i am receiving invalid access token .
I am expecting id_token , access_token and refresh_token from my token endpoint.

But while inspecting the tokens , i see that access_token is not a valid jwt token . It is same as refresh_token . Which means i am unable to use the access_token to access Api resource.

I have local Identity Server against which i tried the same code with corresponding client credentials . To my surprise the access_token i receive is a valid jwt token , which i can use to access api resource. Everything is working fine.

Following is my startup config for oidc

services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromSeconds(1000);
                options.Cookie.Name = "mvcapplication";
            })
            .AddOpenIdConnect(option=>{
		options.Authority = "http://localhost:5000/";
                options.ClientId = "mvc";
                options.ClientSecret = "secret";
                options.ResponseType = "code id_token";
                options.ResponseMode = "form_post";
                options.SignInScheme = "Cookies";
                options.CallbackPath = "/Home/Index/";
                options.RequireHttpsMetadata = false;
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                //Default Scopes
                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("offline_access");
	     });

I am confused why AzureAD is giving me invalid access token?
Is this default behaviour with AzureAD? If so , how can i get API resources?

Adding custom claims

Hello, First of all thank you for creating this sample. I am trying to inject custom user/roles claims to the Todolistservice from my db. I"m currently using IClaimsTranformation in the DI. but it never gets called after i receive the claims. Can one show me where would be the best place to inject custom claims from my db?

Thanks!

Exception to call the web API

Not able to find the responseElement["Title"] after add the todo item since it was add as title with lowercase started.

Deserialize fails with "No parameterless constructor defined for this object"

I tried to get this running with ADAL 3.13, but the Deserialize throws a "no parameterless constructor defined for this object", which seems to come from the json parts of the serialized data.

The error-message itself seems odd at first, but the class AuthenticationResult does indeed not have a parameterless ctor.

How to lock down the app with Roles in Azure AD

Hi,

I implemented the sample and it works as expected. However, one thing I noticed which seemed wierd:

My objective is to be able to lock down web apps/apis using Roles in Azure AD. If I browse to myapps.microsoft.com the app does not appear. However, if I go to the URL directly I can authenticate and add ToDo items.

I want to be able to use Roles to show or hide the app in MyApps but also control who has access to the actual web app. Is this something I need to implement at code level or can it be locked down at AppService and AD level?

Thanks

Update for Visual Studio 2015 RC

I left an issue in a similar repository, but I figured I'd add one here, too.

Is it possible to update this sample from CTP to the current RC? I tried to do this with the mentioned sample and ran into a few issues.

Update sample to beta 4

Specifically (for now), I am interested in the change to

app.UseOAuthBearerAuthentication(options =>
            {
                options.Audience = Configuration.Get("AzureAd:Audience");
                options.Authority = String.Format(Configuration.Get("AzureAd:AadInstance"), Configuration.Get("AzureAd:Tenant"));
            });

I know that it is now UseOAuthAuthentication and I think I have to import the Microsoft.AspNet.Builder namespace, but the parameters/options names have changed and I'm not sure what maps to what.

Recreate and publish to Azure

Despite several attempts, I cannot publish this sample to Azure. It runs locally, but I would really appreciate it if this sample was padded with "How to recreate" and "Publish to Azure" instructions like so many of the other samples have.

Updating Graph token

Hi!
It's not really an issue, it's more question.
When Graph token acquired it has a life time 1 hour. Code that could get this code is:

private async Task OnAuthorizationCodeReceivedAsync(AuthorizationCodeReceivedContext context) { string userId = (context.Principal.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value; var authContext = new AuthenticationContext(context.Options.Authority, new NaiveSessionCache(userId, context.HttpContext.Session)); var credential = new ClientCredential(context.Options.ClientId, context.Options.ClientSecret); var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(context.TokenEndpointRequest.Code, new Uri(context.TokenEndpointRequest.RedirectUri, UriKind.RelativeOrAbsolute), credential, context.Options.Resource); context.HandleCodeRedemption(authResult.AccessToken, context.ProtocolMessage.IdToken); }

As I see this code could be called only if logout and login again. That is not comfortable. Is there some way to change token live time or update it?
I see only way to get new token somehow with code like this:

AuthenticationContext authContext = new AuthenticationContext(LoginUrl + tenantId, false); ClientCredential credential = new ClientCredential(clientId, clientSecret); AuthenticationResult assertionCredential = await authContext.AcquireTokenAsync(GraphUrl, credential);

Abstract API Token request

Hey!
Do you have any suggestions how to abstract the API token request in the controller to avoid the boilerplate each time I do a request to the API?

B2C

please do this same example in B2C scenario

netcore 1.1 version

Has anyone ported this to 1.1?
It is an excellent code base for all kinds of patterns, but a little dated...

ReadMe Step 3: Number 11

Step 3: Number 11: Instruction says:
Find the Client ID value and copy it aside, you will need this later when configuring your application.

Nowhere do I see this "Client ID" of the service being used again in ReadMe. So what is the point of copying it and setting it aside? I suspect this is the reason this sample is failing with AccessDenied. Could you please take a look? Thanks!

Azure B2C AD

Not an issue, just a question...Any chance you have a version of this using B2C? I have been trying to modify your code to use B2C but I am not having any luck.

Cannot access ToDoListService from ToDoListWebApp during registration.

You mentioned in ReadMe #16
In "Permissions to Other Applications", click "Add Application." Select "Other" in the "Show" dropdown, and click the upper check mark. Locate & click on the TodoListService, and click the bottom check mark to add the application. Select "Access TodoListService" from the "Delegated Permissions" dropdown, and save the configuration.
However, I cannot see "Other" in the Show dropdown. What I see are "Microsoft Apps" and "All Apps". Selecting either one displays 4 default apps as follows.
Microsoft Graph
Windows Azure Active Directory
Office 365 Management APIs
Windows Azure Service Management

So I suppose I am stuck! No way to add ToDoListService even though I had registered it successfully. Any help?

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.