ADFS 4.0 OpenID connect customizing access token - oauth-2.0

I have an ADFS 4.0 OpenId Connect setup with Application Group "Web browser accessing a web application". I'm using implicit flow and able to successfully login from my web app receiving id_token and access_token.
Next I'm ussing the access token in requests send from the wep app to API server. What I want to do is customize the access token format - add additional params because by default I only have:
aud, iss, iat, exp, apptype, appid, authmethod, urn, auth_time, ver, scp.
I need the 'sub' param to put the logged username in the access token and some additional params for my api server/resource server to perform custom security logic before giving access to a resource.
How can I customize the access token in this flow in the ADFS 4.0?

Ok, managed to do it by editing web application properties (open Application Groups, double click application group, double click on Web application)
Tab 'Issuance Transform Rules'. Added rules to pass claims from AD like group or name and those claims now appear in the access token.

Related

ADFS2016 SAML2 to OAUTH2/OIDC

We have an MVC application (<myapp.somedomain.com>) .net 4.5.2 (OWIN/ADAL) that uses ADFS2016 for AuthN/AuthZ via OIDC/OAuth2. Users' credentials and attributes are stored in AD LDS. A client (X) requested to authenticate in the application via their IdP over SAML2. Is this possible WITHOUT making changes to the application?
The flow I am looking for; for this client the app’s URL would be (<myapp.somedomain.com/?client=x>). Our ADFS would recognize and redirect the client to their IdP where they would authenticate and than they would be send back to our ADFS along with some predefined claims. Our ADFS would map these claims to an Id Token / Access Token for our application to use. Am I dreaming or is this indeed feasible?
Any links to articles / documentation on how this could be achieved would be most helpful.
As #Wiktor suggests, you could add a SAML client-side stack to your app.
The other way is to federate ADFS with the SAML IDP.
When the user is redirected to ADFS, they use Home Realm Discovery to either redirect to the SAML IDP or authenticate on ADFS directly.
ADFS should handle the token conversions but you may have to fiddle around with the claims rules.

Authenticate and Show an Azure AD secured Web App View from an Third Party App

Background
I have a MVC 5 Web App and hosted in Azure App Service as Web App and secured with Azure AD; Anybody with valid AD credentials can authenticate themselves and view all HTML Content in the Web App;
Objective
I need to give just one of these MVC-View to outside individuals to view. For such we have already created an User in Azure AD which we will be sharing the details with the outside world. Hence, the thrid party will need to write some code to authenticate to our Azure AD and view this HTML content non interactively (Which means without allowing the third party app to prompt to enter user credentials from Azure AD).
What I have thought about
Assume that I am the third Party, I am going to authenticate to Azure AD from a Console/WinForms/HTML
Page and get myself a token; Then I will be using the token, to open
up a Browser to view this page.
Challenges I see
Session Expiration
Session Validity
Putting everything intto a Picture
Please show me some guidence to accomplish the objective.
Hence, the thrid party will need to write some code to authenticate to our Azure AD and view this HTML content non interactively (Which means without allowing the third party app to prompt to enter user credentials from Azure AD).
Per my understanding, you could leverage the OAuth 2.0 Client Credentials Grant Flow by using the client_id and client_secret.
Also, you could use OAuth 2 Resource Owner Password Credentials grant. Note: The resource owner password grant doesn't provide consent and doesn't support MFA either. Detailed tutorial, you could follow here.
Based on the authentication implementation part in your Web App, you could follow the approaches below to implement your scenario:
For using App Service Authentication / Authorization
You do not need to modify any code in your Web App project.
For using Microsoft.Owin.Security.OpenIdConnect middleware
You could use Microsoft.Owin.Security.ActiveDirectory package in your Web App for supporting AAD bearer token authentication, and this middleware need to be configured before the other authentication middlewares as follows:
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = "{the-AAD-clientId}",
Tenant = "{TenantId}"
});
//app.UseCookieAuthentication
//app.UseOpenIdConnectAuthentication
For the client (the third Party), they could leverage the above two flows (Client Credentials Grant Flow ,Resource Owner Password Credentials Grant Flow) to retrieve the access token without user interaction. Then they could access the specific view page by using the token as follows:
Get https://{your-app-name}.azurewebsites.net/home/index
Header Authorization:Bearer {the-AAD-accessToken-or-IdToken}
For retrieving the token, you could follow this tutorial for using User Password Credential flow. For Client Credential, you could just construct the ClientCredential instance when invoking AcquireTokenAsync for getting the token.
Additionally, you could create a new AAD application for this scenario or just use the AAD application for your current Web App. Moreover, there may exists risks when exposing the username & password or clientId & ClientSecret to the third Party, I would recommend you expose a new endpoint for generating the token in your Web App backend and return the token to the third party for security consideration.

oAuth2 security issue with clinet_id and secret key : user can press inspect element and earn clinet_id and secret key

I write a rest api with yii2 and i am using oAuth2 , the problem is when user want login , client web application should send request to get token , request should contain client_id and secret_key and username and password in this case user can simply inspect element and click to network and see posted parameter to the server this means user can see client_id and secret_key.
client_id and secret_key are signature for each application and server can find out witch application use api.
how to handle this security issue?
It seems you have missed out one key element of OAuth 2.0, client type.
OAuth 2.0 defines two types of clients, public clients and confidentiatl clients.
2.1. Client Types
confidential
These are the clients which can protect a credential. They have the
full potential to use authorization code grant type, which obtain
token from backchannel request. Because they use backchannel to obtain
tokens, their credentials are never exposed to end user(via user
agent)
public
Clients which cannot protect credentials. For example SPA clients and
mobile apps comes to this category.
In your case, you seems to have a public client (user agent based application in broswer as it seems). In such case, you should set your client type to a public client. If this is not the case, you are not utilizing a proper back channel call from your web application.
Additionally, public clients which use authorization code flow can use PKCE to avoid authorization code theft attacks. Related RFC can be found from RFC7636

Use External Access Token or Local Access Token

I am developing an application using ASP.NET MVC 5.2.2, Web API 2.2 and Katana/OWIN 3.0. The application uses ASP.NET Identity 2.1 for local accounts and database.
I am using OAuth Authorization Server to generate access and refresh token. I have Android and IOS apps which uses my local oauth authorization server. Android and IOS apps uses SDK to login with Facebook, Google, etc. After that the apps will send the (Facebook/Google/etc) access token to the server. The server will validate access token with Facebook/Google/etc.
If it is valid then,
1) Should I generate new local access token(in Auth header) to apps
for all future request?
2) Should the app send me Facebook/Gmail/etc
access token(in Auth header) every time and the server validate the
access token with Facebook/Gmail/etc each time?
3) If local access
token expire, then the server is using refresh token to generate new
access token. Should the server update the access token as well as
refresh token during this time or updating access token is enough?
after you validate your social provider external access token, you need to exchange this external access token with a local access token issued by your authorization server (Local authority). All the details for this implementation can be found here: http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-angularjs-app/
Let me know if this helps.
Here is the exact steps I have followed to change the external access token with access token issues by Local Authority. The front end is an AngularJS application. You can check the demo application here and see how I'm accessing the web api using Facebook access token http://ngauthenticationweb.azurewebsites.net/
1- AngularJS application sends HTTP GET request to anonymous end point (/ExternalLogin) defined in our back-end API by specifying client_id, redirect_uri, response_type.
2- Once the end point receives the GET request, it will check if the user is authenticated, and let we assume he is not authenticated, so it will notify the middleware responsible for the requested external provider to take the responsibility for this call, in our case it is Google.
3- The consent screen for Google will be shown, and the user will provide his Google credentials to authenticate.
4- Google will callback our back-end API and Google will set an external cookie containing the outcome of the authentication from Google (contains all the claims from the external provider for the user).
5- Google middleware will be listing for an event named “Authenticated” where we’ll have the chance to read all external claims set by Google. In our case we’ll be interested in reading the claim named “AccessToken” which represents a Google Access Token, where the issuer for this claim is not LOCAL AUTHORITY, so we can’t use this access token directly to authorize calls to our secure back-end API endpoints.
6- Then we’ll set the external provider external access token as custom claim named “ExternalAccessToken” and Google middleware will redirect back the end point (/ExternalLogin).
7- Now the user is authenticated using the external cookie so we need to check that the client_id and redirect_uri set in the initial request are valid and this client is configured to redirect for the specified URI.
8- Now the code checks if the external user_id along with the provider is already registered as local database account (with no password), in both cases the code will issue 302 redirect to the specified URI in the redirect_uri parameter, this URI will contain the following (“External Access Token”, “Has Local Account”, “Provider”, “External User Name”) as URL hash fragment not a query string.
9- Once the AngularJS application receives the response, it will decide based on it if the user has local database account or not, based on this it will issue a request to one of the end points (/RegisterExternal or /ObtainLocalAccessToken). Both end points accept the external access token which will be used for verification and then using it to obtain local access token issued by LOCAL AUTHORITY. This local access token could be used to access our back-end API secured end points.

Passing SAML token to a web application

I have an ASP.NET [MVC] application which has a claims based authentication scheme running. ADFS authenticates users and redirects back to the application domain with relevant token.
Now, I'd like to simulate this process from start to end. I was able to get a SAML 2.0 token object of type GenericXmlSecurityToken from ADFS via some powershell scripting but couldn't figure out how to create an SSL tunnel and pass the token to the application just to download the Index view. Any use of net.webclient ?
You have to send SAML 2.0 token to some SP application according with SAMLP standarad.
First, that application have to know how to handle SAML tokens. Second is to send it properly. If you want to send authentication response per instance you have to create HTTP POST request to your application on specific address where it is expecting it.
Take a look over SAML protocol documentation.

Resources