How to access custom sign up field via AD Graph API - azure-active-directory

I'm using https://graph.windows.net with credentials to access user data held within B2C AAD
string graphRequest = $"https://graph.windows.net/mytenancy.onmicrosoft.com/users/" + UserName + "?api-version=1.6"
Where UserName is the ObjectID for that user
I create an object to handle the resulting data, e.g.
displayName
mail
I can deserialize the result and use the info from the profile
I've now edited the SignUpSignIn policy to add a custom field, a string, called StandID
When I view the profile through Postman, the name of that appears to be
"extension_5295e65f1adc497186f72d63f5210d51_StandID": "E35"
However, I cannot seem to access the value via the same method, it comes back blank when I try and access it by the name given
Any idea what I'm doing wrong?

OK, so the answer came in two parts. The first was finding out how to identify the internal name it'd given - I did that by using Postman to show me the whole user profile as a json object
The second part was just a typo - because MSAL and ADAL are incompatible, yet I need to use both, my app is quite complex, and i was passing a value back from the API which I had the wrong receiver set up for in my app, once I realised that it all worked

Related

Verify that a user can only query his own data/information

o/
I'm working on a smaller app, and its going pretty well so far. I talked with a friend about it and he suddenly made me realize something. How do i make sure a user is only able to query his own data from a Database in the cloud?
Its a very simple app, where you can create a user and make some personal shopping lists.
I thought about a couple of options, but I'm not sure what is the right direction to take - or even if any of them is the right one.
The username/id & password is stored locally and appended to the request, and checked against the DB every time.
A token is generated, saved both in the DB & stored locally as a "active" session, and every time a request is send, the token is appended to the request and checked.
...?
I'm sorry if i placed this topic have the wrong tags, since i was not 100% sure where they should be placed.
Well, from your description it seams that you are working on a "no backend" app. If it is the case I suggest you to take a look to Firebase since it will solve all your concerns about authentication and user authorization.
If your would like to use a more custom approach, simply consider that appending the username and a passowrd to a request is always not recommended and since you are using a token is also unnecessary.
Now, returning to the question, i will give you my vision related to contexts where an authentication token is used and thus a backend is needed:
when you log-in a user, you produce a token that is function of the user id
each user request must contain that token
the backend can extract the id of the user that submitted the request from the appended token
a policy or a specific condition will check that data that is going to be retrieved must belong to the user whose id has been extracted.
Hope this could help you

Single Page Application login with Spring and AngularJS

I'am creating application which can be used by unknown and logged in users. Only difference is that logged in user can use some additional functions like saving its content in database.
All communication is based on ajax calls, so what I need is to deny access to some controller functions (end points) in backend for unknown users and on the client side I need to know that it is in logged in state to set this extra functions active. Only one page, login form should be in dialog. I'm little bit confused, because standard Spring Security aproach doesn't fit this case. I was reading this tutorial but I cant't fully understand it.
First: What Principal object does? They send credentials to this endpoint on submit with login() function but where is handled password check? What if I have my users in database?
Second Is it possible to write this configuration in XML style? I guess that it can be done with <intercept-url/> in spring-security.xml file.
Principal Object
The Principal Object is used to be able to get basic information about a user that is attempting to login when using automatic server authentication (i.e. LDAP). However, you will only be able to get a username from the principal object. With a server JBoss/WildFly, for example, you can link the server to Active Directory to allow Microsoft Windows to authenticate users.
Simple Solution
First, Spring Security will add additional complexity to your application where it doesn't sound like you are trying to do that. Instead, use a simple Servlet Filter. If you are using LDAP on a JBoss/WildFly sever, you can make a POST to j_security_check and the server will send the request to the filter if correct credentials are provided. Inside the filter, you may use the getName() function of the Principal object to get the username so that you may store it in the user's session. However, if you are not using LDAP, you may make a simple POST to a Java Servlet or Spring Controller (with an #RequestMapping) to attempt to login the user and store the user's information in the session.
At this point, you can filter out what URLs you will allow users to see. For example, the URL that contains /administrator/some/other/stuff.jsp could be restricted if the URL contains the word "administrator" in the first directory of the URL.

Azure B2C Issues and Questions

I've been working with the Azure B2C for a couple of days now and have a few issues and questions:
Url that it creates to redirect for login is formed incorrectly. It contains a question mark twice - after the url, and again after the profile name. This causes a 404 not found error every time you login, log out, etc. For example, the URL it tries to redirect to for login looks like this: https://login.microsoftonline.com/samlmanbc.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_firstdemoprofile?client_id=08fcblahblah. You'll notice a second question mark after the profile name, and that's what breaks it.
If I fix that and try and log in, it doesn't recognize the username / password of my account that's a global admin. It DOES recognize the username / password of a new user I created locally in the directory.
In the OnRedirectToIdentityProvider method, when the request type is authentication, the AuthenticationResponseChallenge is null, which makes this call fail:
OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary[Startup.PolicyKey]);
I worked around this by using the static string SignInPolicyId for the second parameter. That works fine when an account already exists, but if it doesn't then Azure fails at login and says an account doesn't exist for the user. So what is the right value to use there, and/or how does one initialize it so it isn't null?
The type of a claim that was added to a profile is preceded with "extension_"; is that always going to be true or just for now? For example, I added a property called "favoriteTeam", but the claim type for it is "extension_favoriteTeam".
When you use FaceBook as an identity provider, is there any way to pass along the Facebook access token claim (http://www.facebook.com/claims/AccessToken)? This was useful when using ACS with Facebook because your app can then use that token to make additional calls to Facebook to get data from it.
In relation to issue 1 - I updated my reference Microsoft.IdentityModel.Protocol.Extensions to v1.0.2.206221351 and it started working. I made some updates to other references before this, so if the first one doesn't work, try updating more assemblies from nuget.
This is as expected. A page that signs in "local account" users will not sign in your work or school account (in this case, the global admin user).
Always going to be true. We will be cleaning up the Admin UX to make this more clear.
This is on our roadmap. No ETA as yet.

What's the simplest way to get user Groups from WAAD?

I've got AngularJS and Web.API WAAD authentication up and running. For client side I use great library ADAL.JS. For backend I use Microsoft.Owin.Security.OAuth. This part went quite smooth.
Now I want to implement authorization based on roles (which will be mapped to WAAD groups). Groups are not included in authentication token so I must ask Azure Graph API for them. I saw various ways to do it, using custom claims providers, adding web services to project, etc. Some examples already providing mapping between groups and roles to use in [Authorize] attribute.
But what is just the simplest example of how to get a list of group ids/names from WAAD providing User ID or username, when I'm already authenticated?
Also, is there any way to get this data in JS to use in Angular frontend, or should I create an API service which Angular should call for roles info?
In the non-JS case, the simplest way of getting groups in the token is by opting in. Download your application’s manifest, locate the “groupMembershipClaims” entry, change its value to “SecurityGroup” or “All”, upload back the manifest.
However note that this won't work for your scenario, because it uses the implicit grant - here the token is returned in an URI fragment, hence a big token would risk blowing past the URL length limits of the browser.
You can always request groups to the Graph and make it available to your frontend via custom action on your API, but from what you wrote you are already familiar with that. Let me discuss the matter here - if there's a simpler route to make this work in SPAs, I'll get back to this thread.
HTH
V.
Update: I verified and in the implicit grant case you will receive groups always via the overage claim. Please refer to https://github.com/AzureADSamples/WebApp-GroupClaims-DotNet/tree/master/WebApp-GroupClaims-DotNet - it will show you how to process the overage claim to retrieve groups. All you need to do is apply the same guidance to a web API instead, and if you need to make the info available to the client expose one or more actions doing so.

How to "hang on" to Angular scope variables after authentication via OAuth service (like google)

Here's the problem I am trying to solve (I'm 100% sure I'm asking the "right" question) in my node.js / angularJS web application:
Authenticated members of the app can "invite" anyone with an email address.
Invitees can register using google (OAth 2.0) or with their email address and password.
In either scenario, it's possible that the invitee chooses to register with an email address (either a google one or one they type in) that differs from the email to which the invitation was sent.
I want to associate the two emails, and am having trouble figuring out how to do so.
My current approach:
The URL in the invitation email includes a unique parameter which references the email of the recipient. When that link is followed, I store that parameter using an angular service - the same that I use for storing the user once they are authenticated.
The problem (or at least one of them):
When I call the google authentication and it, subsequently returns the user to my site via the callbackUrl, my angular service instance no longer has a reference to the initial invitee's email, which I assume is expected since I the user left the angular application and then returned. Thus, I can't compare it to the email returned by the google authentication and, if they are different, prompt the user, join them, whatever.
What is the best way to toss that reference I take from the link that first took the user to the site to the other side of the OAuth process?
Or, is there a different approach entirely I should consider?
You would be able to pass a state parameter in your oath request. Google then returns the same parameter back with the oath response:
https://developers.google.com/accounts/docs/OAuth2UserAgent -> paramater: state

Resources