Reputation: 33
Idea is to build a Spring Boot Java app with which we can get MS Outlook personal account holder's calendar data, say upcoming events. Based on initial research I found out that MS-Graph API is the answer for the same, and I started with this tutorial as a starting-up code.
My application.yml file looks like this:
spring:
cloud:
azure:
active-directory:
enabled: true
profile:
tenant-id: common
credential:
client-id: <from azure portal>
client-secret: <from azure portal>
authorization-clients:
graph:
scopes:
- https://graph.microsoft.com/User.Read
- https://graph.microsoft.com/Calendars.Read
- https://graph.microsoft.com/Calendars.ReadWrite
- https://graph.microsoft.com/Analytics.Read
tenant-id is set common as I want to connect with any personal outlook account holder. On the Azure portal supported account types are set as - "Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)" enter image description here
To test whether or not I could reach out to the MS-Graph Calendar API I added the below-mentioned code (coming from here):
EventCollectionPage events = graphClient.me().calendar().events()
.buildRequest()
.get();
I could able to connect to the Outlook calendar and fetch the events for my own account which happen to be the same account with which the Azure portal is being accessed. Thus my personal account [email protected] is also the admin account of the tenant in which the app is registered.
But when I am trying to connect to another personal outlook account, which is created by me and I added some events in the associated calendar for testing purposes I am failing. This new outlook personal account is surely not in the tenant in which the app is registered, I am not very sure which tenant the personal MS accounts go into, and how to add service-principals to them.
After configuring the app registration for all accounts on the azure portal and making the tenant-id as common in my application.yml file I was expecting to connect all the personal accounts whomsoever signed up for the Java app but faced the following errors. It seems as if the Microsoft identity platform is not letting this other user connect its calendar to my Java app, as the service-principals of my app are not stored in the personal account holder's tenant. But How to do that? Is my approach to problem is right or should I instead of leveraging Spring libraries (OAuth2Client, AzureActiveDirectory) prefer building OAuth2.0 client on my own, reaching to /authorize and /token endpoints on my own, though MS doesn't recommend that as mentioned here?
java.lang.IllegalArgumentException: Missing attribute 'name' in attributes
at org.springframework.security.oauth2.core.user.DefaultOAuth2User.<init>(DefaultOAuth2User.java:72) ~[spring-security-oauth2-core-5.6.7.jar:5.6.7]
at org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser.<init>(DefaultOidcUser.java:93) ~[spring-security-oauth2-core-5.6.7.jar:5.6.7]
at org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser.<init>(DefaultOidcUser.java:67) ~[spring-security-oauth2-core-5.6.7.jar:5.6.7]
at com.azure.spring.cloud.autoconfigure.aad.implementation.webapp.AadOAuth2UserService.loadUser(AadOAuth2UserService.java:134) ~[spring-cloud-azure-autoconfigure-4.3.0.jar:4.3.0]
at com.azure.spring.cloud.autoconfigure.aad.implementation.webapp.AadOAuth2UserService.loadUser(AadOAuth2UserService.java:52) ~[spring-cloud-azure-autoconfigure-4.3.0.jar:4.3.0]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:156) ~[spring-security-oauth2-client-5.6.7.jar:5.6.7]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.6.7.jar:5.6.7]
at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:195) ~[spring-security-oauth2-client-5.6.7.jar:5.6.7]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:223) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.doFilterInternal(OAuth2AuthorizationRequestRedirectFilter.java:178) ~[spring-security-oauth2-client-5.6.7.jar:5.6.7]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:117) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221) ~[spring-security-web-5.6.7.jar:5.6.7]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) ~[spring-security-web-5.6.7.jar:5.6.7]
Upvotes: 1
Views: 2132
Reputation: 11
Use this sample to learn how to call graph
Individuals are the administrators of their personal accounts. When they go to log into your application, there will be a list of actions that they need to consent to before they before they can use your application. In your case, one of them would be something like "read calendar." The individual would then grant your application the ability to read their outlook calendar. Hope this helps Vyassa.
Upvotes: 1
Reputation: 136
spring-cloud-azure-starter-active-directory
is designed to support Work/School account
. Whether Personal account
is supported is not sure for now. It's tracked in this GitHub issue.
For the difference between Work/School account
and Personal account
, please refer to this page.
Upvotes: 1