Requesting JWT from ADFS 2016 using custom attribute - c#

We are looking into a way to request a JWT token from ADFS 2016 via webservice call by sending a user UID, which is stored in a database or in AD LDS. The token should contain the full domain username as a claim. A C# service would request the token without user GUI interaction (UID provided by an ID card), and then forward it to an intranet web application.
Is this possible with OAuth 2.0 or WS-Trust 1.3 in ADFS 2016, and what steps would be involved?
Right now I have tried using OAuth 2.0 (HTTP POST to /adfs/oauth2/token), but haven't been able to correctly configure ADFS (application groups, relaying parties, ...) and sending the correct HTTP parameters to even get a token by providing username/password.
It would be great if somebody could point me in the right direction.
EDIT
A more detailed description of what we want to achieve:
Goal is to create a windows service which handles NFC card login and sends JWT with user information to arbitrary web applications.
C# windows service reads card UID from a NFC card reader.
Windows service requests JWT from ADFS by providing card UID. That can be OAuth or WS-Trust, whichever works.
ADFS looks up card UID from a confidential database. The database entry also contains the username. It could then further enrich this data by finding the domain user in ADLDS.
ADFS creates token containing at least the domain user name and sends it back to the C# windows service. No user interaction with ADFS login screens required.
Windows service receives token and forwards it to preconfigured web application login handler.
Web application validates token signature and handles login.
The credential in this case would solely be the card UID. Is this possible with ADFS? If not, my backup plan would be to create the token directly in my windows service.

Related

ASP NET API - Authenticate users using Azure AD SAML Protocol without open Microsoft Login Page

It's my first time with Azure AD and SAML protocol, I want to know if it's possible to add a user authentication request to Azure AD without being redirecting to Microsoft Login Page? If so, how it can be done?
Basically, I want to send the email and password and authenticate to Azure without leaving the page of my Mobile application
The SAML specification supports the SP sending the user name in the SAML authn request to the IdP. However, not all IdPs support this. The SAML specification does not support sending the password. Therefore, unless the user is already logged in at the IdP, they will always be prompted to enter their password.

OAuth2 Resource Owner Password Grant via API

I am currently building an API which requires OAuth2, but cannot find a library to use that will handle the single sign on in a native mobile app via RESTful API only. Most I've found only have a web popup, which has been vetoed for this project. B2C, which is currently functioning, is not capable of using ROPG. Is there a way to easily set this up with another library using C#.NET and Azure?
UPDATE:
Attempting to use B2C per Fei Xue answer below, we got to the point of getting an access token from Microsoft Graph.
In the body of the POST, we did the following:
resource=https%3A%2F%2FGraph.windows.net&client_id=[B2C Settings -
Applications -
AppId]&grant_type=password&username=rob%40[tenant].onmicrosoft.com&password=[password]&client_secret=[B2C Settings - Applications - App Key - client_secret]
Our error with the namespace was due to the usernames we were trying. This is a B2C tenant using email as the username and that was the reason for the namespace error. The only way we got past that error was to create a B2C user with the email address ending in the tenant, like so:
rob#[tenant].onmicrosoft.com
We are getting an access token now, but that token does not authenticate with our azure app service api app, which was the original goal.
What we are trying to accomplish is to send the username and password that is valid for a B2C signin and get an IdToken or Access Token that is valid for the api app. The api app connects to B2C via App Service Authentication settings configured for AAD with the Client ID and secret setup from the B2C Settings Application.
UPDATE:
Attempting to pass through the graph.windows.net token for authentication in our Azure web api, we added in the https://Graph.windows.net allowed token audience in our App Service – Authentication – Active Directory Authentication configuration.
However, passing the graph access token in the Bearer header to the API still results in
“Authorization has been denied for this request”.
Found out that if we make the Issuer Url blank like in the example below, it now accepts the Graph token!
However, this causes issues when trying to hit
https://[our_web_app].azurewebsites.net/.auth/login/aad
It goes to the common Microsoft login now. Previously it directed to our B2C sign up in policy because the Issuer Url was set to:
https://login.microsoftonline.com/[tenantname].onmicrosoft.com/v2.0/.well-known/openid-configuration?p=[B2C_SignUpIn_Policy]
In fact, if we also pull up the policy from within our app (which was working before removing the Issuer Url) to the sign in policy, we can sign in, but that returned Access Token now always comes back as Unauthorized in the web API calls.
Should the Issuer Url be left blank?
Also, since making the Issuer Url blank, the server takes much longer to respond to API calls when we send a request using a Graph access token in the Header Authorization Bearer. It went from taking about 1-2 seconds (using a valid B2C access token obtained from MSAL or the web login above) to taking about 10-15 seconds to respond that it is an authenticated request. That kind of speed is a show stopper for us. Does validating a graph call in this manner normally take this long?
The feature is now available in preview and works pretty well:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-ropc
Important note: The POST url mentioned in the documentation is wrong.
https://login.microsoftonline.com/{{Aad_Tenant}}/b2c_1_ropc_auth/oauth2/v2.0/
Must be:
https://login.microsoftonline.com/{{Aad_Tenant}}/oauth2/v2.0/token?p=b2c_1_ropc_auth
The calling application must have native client enabled, otherwise you will get this error:
AADB2C90224: Resource owner flow has not been enabled for the application.
The Azure AD B2C has already support the Resource Owner Password Grant flow, you can send the HTTP request like below to using this flow:
POST: https://login.microsoftonline.com/{tenant}/oauth2/token
resource=https%3A%2F%2FGraph.windows.net&client_id={client_id}&grant_type=password&username={userName}&password={password}&client_secret={secret}
Note: this flow only work for the local accounts as social identity providers(Facebook, Google, etc) don't support this.
Update
The token above is acquiring the token for https://graph.windows.net. To pass through the authentication of web API which protect by Azure AD, we need to specify this as the ALLOWED TOKEN AUDIENCES like figure below:
Update to the answer from #AlexAIT.
The URL in the documentation now works for AD B2C.
https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/B2C_1A_ROPC_Auth/oauth2/v2.0/token
https://learn.microsoft.com/en-us/azure/active-directory-b2c/add-ropc-policy?tabs=app-reg-ga&pivots=b2c-user-flow#test-the-ropc-flow
If you get the error:
AADB2C90224: Resource owner flow has not been enabled for the
application
Navigate to application -> Authentication and select Enable the following mobile and desktop flows:.
Wait a few minutes and then it will start to work.
Github thread:
https://github.com/MicrosoftDocs/azure-docs/issues/50330
I work with Rob, and we did finally get the call to work with
https://login.microsoftonline.com/[tenant_ending_in_onmicrosoft.com]/oauth2/token
In the body of the POST, we did the following:
resource=https%3A%2F%2FGraph.windows.net&client_id=[B2C Settings - Applications - AppId]&grant_type=password&username=rob%40[tenant].onmicrosoft.com&password=[password]&client_secret=[B2C Settings - Applications - App Key - client_secret]
Our error with the namespace was due to the usernames we were trying. This is a B2C tenant using email as the username and that was the reason for the namespace error. The only way we got past that error was to create a B2C user with the email address ending in the tenant, like so:
rob#[tenant].onmicrosoft.com.
We are getting an access token now, but that token does not authenticate with our azure app service api app, which was the original goal. What we are trying to accomplish is to send the username and password that is valid for a B2C signin and get an IdToken or Access Token that is valid for the api app. The api app connects to B2C via App Service Authentication settings configured for AAD with the Client ID and secret setup from the B2C Settings Application.
UPDATE:
If I add ?p=[B2C SignUpIn Policy] to the POST, then we get the following error:
AADB2C90224: Resource owner flow has not been enabled for the
application.

Web Service authentication using CA siteminder in winform application

I don't have much experience with CA sitemider so please bear with me, if I am asking silly question.
I am creating a excel add-in which uses win-forms for the interface. I have added a Web reference of a web-service which I need to call to perform operation. The web-service supports the SAML authentication. So my requirement is, I need to validation the user from the Active Directory using CA sitemider and get the token (like access token or auth token) and then pass it to the webservice.
I'm not sure how can I implement this? What should I do to get that token and also do I need to use the web browser control in winform to implement the siteminder authentication flow?
Check the System.IdentityModel namespace for this , you can implement via Windows Identity foundation. The namespace has validators for SAML1/2 tokens. To request a valid SAML token and pass it to your webservice you might need to configure an interface which can get you the token first.
How Siteminder sends the token is same as other Identity providers, the user has to be a valid user of IDP (Siteminder in this case), once the request goes to Siteminder, it shows its login page and once user logs in the server returns a SAML token (try using 'SAML parser' extension of firefox to see how the token looks when its returned). You can extract the token in your interface after request is sent back to your end from Siteminder, then validate it (if needed) and send it to your webservice.

How to receive IdP token manually?

I'm trying to build this scenario in windows client:
Picture of my desired scenario
Steps I did:
Client starts; it opens a window with a choice of the identity providers
End-user choose one of the identity providers (let's say Google)
It goes to next tab, where web-browser navigates to Google sign-in screen.
User signs-in, and authentication token (user id, etc.) are received.
Now I can login using Mobile Services, and access Azure tables, all is fine.
But now we want to use WCF service. How to obtain the IdP token in this scenario, to be used to obtain ACS SWT Token. I have access token, authentication token, user id, and much more information from IdP, but how can I either catch or forge IdP token from these informations?
I want to be able to access Azure table in a WCF service, while having the identity of a signed user from the client-side?
OK, after intensive search, I've found these links useful:
Azure ACS on Windows Phone 7
How To: Obtain SWT Security Token
How To: Display List Of Identity Providers
How to: Authenticate to a REST WCF Service

Is it possible to perform authentication with known user and password?

Given a valid username and password, could I perform an authentication (basicly to know if user and password are ok) using OAuth, OAuth2 or OpenId?
I need is to call the authentication server to know if a user and password is valid or not.
Update
Actually I found a document where explains that OAuth2 supports this mechanism:
Nevertheless, OAuth2 also supports scenarios in which the user tells
the client his username and password. In such cases, the client
transfers this information as well as the client ID and the client
secret and the desired scope to the authorization server and then
obtains the desired token directly without another call.
So, the next question is, please, could you provide a working example of it?
The OAuth 2.0 spec defines several different use cases or workflows targeted to different kinds of applications or authorization scenarios.
One of the authorization workflows, and the one most commonly associated with Oauth, is when a client application requests access to a protected resource but does not obtain the end user's credentials directly - the access request redirects to present the end user with a login screen owned by the authorization system, not owned by the client application. When the user presents credentials and agrees to allow the client app's request for access, then the authorization server returns an authorization code to the client app and the client app can use that code to obtain an access token to access the end user's protected resources.
That's called the authorization code grant, and it's detailed in section 4.1 of the OAuth2 spec.
There is another authorization workflow in which the client app does have possession of user credentials or some other form of shared secret. The client application includes the user credentials or shared secret when requesting an access token. This is called a client credentials grant, and is detailed in section 4.4 of the Oauth2 spec.
The client credentials grant may be closest to your scenario.

Categories