blazorade / blazorade-teams Goto Github PK
View Code? Open in Web Editor NEWA Blazor component library that is designed to be used when building applications for Microsoft Teams.
License: MIT License
A Blazor component library that is designed to be used when building applications for Microsoft Teams.
License: MIT License
HI! I've a Blazor Webassembly app with the sample. Everything is ok but in the first execution, the app don't login the user after the login popup.
I need to refresh the page to components like ProfileViewer works.
You can reproduce the steps by delete all local storage and cache in Teams devtools and open the app.
For instance, the app open then shows the message above, open login popup and do a successful authentication but don't refresh the AuthResult of ApplicationContext.
Can you help me?
'ello
Could you make this work with Single Sign-on please?
Regards
Hein
In the suggested code for AuthenticateRequestAsync,
var authResult = await this.MsalService.AcquireTokenSilentAsync(loginHint: this.Context?.Context?.LoginHint, fallbackToDefaultLoginHint: true);
this error occurs: No account object provided to acquireTokenSilent and no active account has been set. Please call setActiveAccount or provide an account on the request.
I believe I have followed the example instructions correctly. If any guidance can be provided, I would appreciate.
Running latest beta for Blazorade and Blazor in .NET 5
thx.
I have a Teams personal tab app that is using Blazorade.Teams to handle authentication. When running the app in Teams desktop app or Teams web app, everthings works fine. Running the app in Teams app on my iPhone, the HostNotAvailableTemplate is rendered.
We need more support for functions on the microsoftTeams
module to be included in the BlazoradeTeamsInteropModule
module.
This issue defines the following interop functions to be supported.
Blazorade Teams should support tab applications that can be added to group chats.
Blazorade Teams must support the simplest for of tab application, personal tab application.
I've tried following the getting started section in the wiki as well as modifying parts of the BlazorServer sample, but both lead to the AuthenticationProvider throwing this exception:
`
Unhandled exception rendering component: Code: generalException
Message: An error occurred sending the request.
Status Code: 0
Microsoft.Graph.ServiceException: Code: generalException
Message: An error occurred sending the request.
---> Blazorade.Core.Interop.FailureCallbackException: Exception of type 'Blazorade.Core.Interop.FailureCallbackException' was thrown.
at Blazorade.Core.Interop.DotNetInstanceCallbackHandler`2.GetResultAsync(Nullable`1 timeout)
at Blazorade.Teams.Interop.AuthenticationModule.AuthenticateAsync(TokenAcquisitionRequest request)
at Blazorade.Teams.Interop.AuthenticationModule.AuthenticateAsync(String loginHint, IEnumerable`1 scopes)
at TeamsTest.Authentication.AuthenticationProvider.AuthenticateRequestAsync(HttpRequestMessage request) in C:\Projects\TeamsTest\Authentication\AuthenticationProvider.cs:line 22
at Microsoft.Graph.AuthenticationHandler.SendAsync(HttpRequestMessage httpRequestMessage, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
at Microsoft.Graph.HttpProvider.SendRequestAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at Microsoft.Graph.HttpProvider.SendRequestAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at Microsoft.Graph.HttpProvider.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at Microsoft.Graph.BaseRequest.SendRequestAsync(Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.BaseRequest.SendAsync[T](Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.UserRequest.GetAsync(CancellationToken cancellationToken)
at TeamsTest.Shared.UserInfoView.OnParametersSetAsync() in C:\Projects\TeamsTest\Shared\UserInfoView.razor.cs:line 38
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)`
I have registered my application the way it is described in the wiki and I tried setting the redirect URL to the root of my application as well as the login page (wiki says root, but this article uses the login page)
Is there any way to get more information about the error so that I can narrow this down?
The TeamsApplication
component should take care of all the necessary initialization of the application. This initialization would provide the application with the context information that the Teams SDK provides applications with the getContext SDK function.
Create a Blazor component that is used as the container component for all tab applications. This container component will take care of:
The component, TeamsApplication
, handles all JS interop required to perform those tasks and will provide the necessary information through a context parameter that is sent to the template exposed by the component. This template is rendered only after all initialization tasks have been completed by the TeamsApplication
component.
To use this component, a developer would only need to write the following code in a .razor
file.
<TeamsApplication>
<ApplicationTemplate>
@context.Context.LoginHint
</ApplicationTemplate>
</TeamsApplication>
That would show the login hint that has been read from the Teams SDK.
To have the TeamsApplication
component take care of authenticating the user with Azure AD, a developer would write the following.
<TeamsApplication RequireAuthentication="true">
<ApplicationTemplate>
Authenticated User: @context.AuthResult.IdTokenClaims["preferred_username"]
</ApplicationTemplate>
</TeamsApplication>
There seems to be a problem if you try to use Blazorade Teams without an app id as explained here. E.g. if I use the serverside sample app and change this (from here)
.AddBlazoradeTeams((p, c) =>
{
var root = p.GetService<IConfiguration>();
var config = root.GetSection("teamsApp");
c.ClientId = config.GetValue<string>("clientId");
c.TenantId = config.GetValue<string>("tenantId");
c.LoginUrl = "/login";
c.DefaultScopes = new string[] { "User.Read" };
});
to
.AddBlazoradeTeams();
I run into
Exception has occurred: CLR/System.AggregateException
An unhandled exception of type 'System.AggregateException' occurred in Microsoft.Extensions.DependencyInjection.dll: 'Some services are not able to be constructed'
Inner exceptions found, see $exception in variables window for more details.
Innermost exception System.InvalidOperationException : Unable to resolve service for type 'Blazorade.Teams.Configuration.BlazoradeTeamsOptions' while attempting to activate 'Blazorade.Teams.Interop.BlazoradeTeamsInteropModule'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
...
Am I missing something?
If you have an application that requires authentication (setting RequireAuthentication="true"
on TeamsApplication
), the authentication does not work when the application is running in the Teams desktop client.
The problem seems to be that loginPopup
in MSAL does not work in the desktop client. We need to change the popup to use the built-in popup in Teams and follow the principles in the PnP sample.
We have a multi-tenant, multi-authentication application. Depending on if the application is running in Teams, determined via your TeamsApplication template we decide which HTTPClientFactory code to use as below:
Here's an excerpt from the client factory code:
httpClient = _httpClientFactory.CreateClient(HttpClientNames.ApiClientTeams);
var scopes = _configuration["DataSettings:Scopes"].Split(',');
var authResult = await _blazoradeMsalService.AcquireTokenSilentAsync(_teamsApplicationContextState.ApplicationContext.Context.LoginHint, scopes);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
Here is the App.razor:
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
<Found Context="routeData">
<TeamsApplication RequireDefaultScopes="true" RequireScopes="@Configuration["DataSettings:Scopes"]" RequireAuthentication="true" >
<ApplicationTemplate Context="ctx">
<ShareApplicationContext Context="ctx" />
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
</ApplicationTemplate>
<HostNotAvailableTemplate>
<CascadingAuthenticationState>
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
@if (!context.User.Identity.IsAuthenticated)
{
<RedirectToLogin />
}
else
{
<p>You are not authorized to access this resource.</p>
}
</NotAuthorized>
</AuthorizeRouteView>
</CascadingAuthenticationState>
</HostNotAvailableTemplate>
<LoadingTemplate>
We're loading here!
</LoadingTemplate>
</TeamsApplication>
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
The issue we are having is when trying to fetch the access token, it is unable to find an account associated with the login hint/auth request we pass to it. This issue also occurs when we pass the token directly from the teams context directly. Any ideas why this might be happening?
As an aside, it would be worth having some documentation on multi-auth solutions in the run-up to a version 1.x release as it seems like it may be a very common use case for a library like yours.
Blazorade Teams should support applications that are added to meeting tabs.
When using the TeamsApplication
component, it must be possible to specify which scopes the application requires, so that the builtin authentication mechanism can acquire a token that grants those scopes. This would be specified as a parameter on the TeamsApplication
component.
In addition, we must also support an option where default scopes can be configured in the options for the application. These default scopes should be used in case scopes are not explicitly defined.
The TeamsApplication
component will have the following two parameters:
RequireDefaultScopes
: A boolean value specifying that the application should have access to the scopes configured as default scopes for the application.RequireScopes
: A comma-separated string value defining the scopes that the application requires. If RequireDefaultScope
is true
, then the default scopes will be combined with the scopes specified in this parameter before acquiring a token for the combined set of scopes.With these two new parameters, the RequireAuthentication parameter will be removed as obsolete.
Let me say first that I'm new to both Teams and Blazor development. I'm trying to use Blazorade.Teams with Blazor WASM to also access a Server Side Web API that is secured with Azure AD. The authentication dialog appears when I open my tab in Teams but I get an error in the browser console "Value cannot be null. (Parameter 'json') in the blazoradeTeams.js file. I have downloaded the sample and it works properly so I know it is something that I'm doing wrong on my side, I just can't figure out what that would be.
Here is my Program.cs:
`
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add("#app");
builder.Services.AddBlazoradeTeams((provider, config) =>
{
var myTeamsApp = provider
.GetService<IConfiguration>()
?.GetSection("myTeamsApp");
config.ClientId = myTeamsApp.GetValue<string>("clientId");
config.TenantId = myTeamsApp.GetValue<string>("tenantId");
config.LoginUrl = "/login";
config.DefaultScopes = new string[] { "User.Read" };
});
builder.Services.AddHttpClient("Forms.Web.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("Forms.Web.ServerAPI"));
builder.Services.AddMsalAuthentication(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("api://{Client ID}/API.Access");
//options.ProviderOptions.LoginMode = "redirect";
});
await builder.Build().RunAsync();
`
Thanks for any help you can give,
Greg
It would be great if the TeamsApplication
component could provide information about the client's time zone offset, for instance with the ApplicationContext
class.
The client time zone is probably used in many applications, so providing that in a central way would be a good enhancement.
I would like to have a single application that works in both "Teams" and in a browser.
For example in browser mode, I need a menu but not in "Teams" mode.
I tried using and in MainLayout.razor to set up the layout. But it doesn't work as expected.
It's always the that's displayed.
Could you help?
Thank you
Blazorade Teams must support tab applications that can be added to a channel in a team.
The following Teams SDK functions in the microsoftTeams module must be supported by Blazorade Teams.
I'm trying to wire up the Blazorade Teams NuGet and the app is acting like its not authenticating. In the documentation it doesn't have adding the 2 javascript references to the index.html like the package reference project does.
Are they no longer needed? If they are I'm guessing they'd need to look like
<script src="https://statics.teams.cdn.office.net/sdk/v1.7.0/js/MicrosoftTeams.min.js"></script>
<script src="_content/BlazoradeTeams/js/blazoradeTeams.js"></script>
<script src="_content/BlazoradeTeams/js/blazoradeMsal.js></script>
Blazorade Teams must support both server and WebAssembly hosting models.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.