I am using below settings in ADAL to access Azure AD.
this is settings someone used and I found in internet
public const string ApplicationId = "your-application-id";
public const string ReturnUri = "http://your-uri.com/";
public const string Authority = "https://login.windows.net/common";
public const string GraphResourceUri = "https://graph.windows.net";
this is my setting
public static string ApplicationID = "xxxx-xxxx-xxxx-xxxx-xxxxx";
public static string ReturnUri = "http://myAppName register in AzureAD";
public static string tenanturl = "https://login.microsoftonline.com/xxx-xxx-xxx-xxx-xxx";
public static string GraphResourceUri = "https://graph.microsoft.com";
Problem:
I hope someone can confirm the following:
a) Is Authority is same as tenanturl ? which one to use: login.windows.net or login.microsoftonline.com
b) which to use for GrapResourceUri: graph.windows.net or graph.microsoft.com
c) are the settings in 1 and 2 complete? or there is more settings to add.
d) the token return from Azure AD is SAML or JWT token?
a) Is Authority is same as tenanturl ? which one to use: login.windows.net or login.microsoftonline.com
Authority should be https://login.microsoftonline.com/your-tenant-id-here.
You can use either the unique id for your AAD tenant or one of the verified domain names, e.g. https://login.microsoftonline.com/mytenant.onmicrosoft.com.
b) which to use for GrapResourceUri: graph.windows.net or graph.microsoft.com
If you want to call Azure AD Graph API, the first. If you want to call Microsoft Graph API, you use the second.
c) are the settings in 1 and 2 complete? or there is more settings to add.
Sadly the answer is it depends.
There are many flows for acquiring an access token in Azure AD, and which one you use (and thus which overload of AcquireAccessToken() you use) depends on the type of your application and what is the situation.
The settings here are enough for a native application (which yours is I guess since the Xamarin Forms tag is there).
Related
I'm building a library type module for DNN that will house a Web API service that is meant to be called by a separate application. It has one controller that inherits from DnnApiController. I'd like the requests in this service to use basic auth, since the other app has no association with DNN and its users won't be interacting with the portal. All it can do is pass in a username and password (this will happen over SSL). We are running DNN 7.3 which is configured to use standard Forms authentication.
Is it possible to configure just this service to use basic auth? If so, what attributes/configuration would I need to make it work?
I think you can do this with the DNNAuthorize attribute. First, I would add a role into DNN, example "ExternalApp". Then create a DNN user that has that role.
Make your web service code look like this:
public class MyAPIController : DnnApiController
{
[HttpGet]
[DnnAuthorize(StaticRoles="ExternalApp")]
public string Ping()
{
return "MyAPI Version 01.00.00";
}
}
Then in your external application (let's assume it is written in C#), you can do something like this:
string scheme = "https://";
string domainAlias = "www.website.com";
string modulePath = "myapimodule";
string controllerName = "myapi";
string apimethod = "ping";
Uri serviceUri = new Uri(string.Format("{0}{1}/DesktopModules/{2}/API/{3}/{4}", scheme, domainAlias, modulePath, controllerName, apimethod));
HttpWebRequest httpReq = (HttpWebRequest)HttpWebRequest.Create(serviceUri);
httpReq.Credentials = new NetworkCredential("externalappUser", "password123");
httpReq.Method = "GET";
httpReq.Accept = "application/text";
httpReq.BeginGetResponse(HttpWebRequestCallBack, httpReq);
I have a Winform client that we are slowing changing inline SQL data calls into ASP.NET Web API calls. We currently use the WindowsPrincipal.IsInRole check in the Winform client to determine if the user can run the SQL data calls. We would like to move into a Claims type setup where both the Winform client and the Web API can check the roles "claims" of a user.
I can't seem to find any "good" articles on how to get a Winform client to (1. Pass the claim to the service) and (2. Use a claim check inside the Winform client like the IsInRole). Any help or push in the right direction would be great.
--EDIT
So I used this article http://zamd.net/2012/05/04/claim-based-security-for-asp-net-web-apis-using-dotnetopenauth/ as a sample on getting a token back from the server but the article does not show how to get the claims identity out of the http client. Any idea how to get the claims identity out of the http client?
While I haven't tested this code, hopefully it will get you moving in the right direction.
I believe to answer your question you do this in your ClaimsAuthenticationManager where upon validating the token received from the server you set the Thread.CurrentPrincipal -- the same way you do on the web side without setting the HttpContext.Current.User principal.
Again this isn't tested but I think it would look something like this...
In my Token Validator I have the following code:
public static ClaimsPrincipal ValidateToken(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(new JwtSecurityToken(token),
Constants.TokenValidationParameters);
return FederatedAuthentication.FederationConfiguration
.IdentityConfiguration
.ClaimsAuthenticationManager.Authenticate(token, claimsPrincipal);
}
public static string GetToken(string username, string password)
{
OAuth2Client client = Constants.OAuth2Client;
AccessTokenResponse response = client.RequestAccessTokenUserName(username.ToLower(), password,
Constants.AllowedAudience);
return response.AccessToken;
}
Within my ClaimsAuthenticationManager I have modified the following code as you don't want to set the HttpContext in a non web environment:
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return base.Authenticate(resourceName, incomingPrincipal);
}
/* HttpContext.Current.User = */ Thread.CurrentPrincipal = incomingPrincipal;
return incomingPrincipal;
}
I believe you then just have to set the appropriate keys in the app.config, specifically the system.identityModel => identityConfiguration => claimsAuthenticationManager
Once the thread you are running on has the "Authenticated Principal" you should be able to call the ClaimsPrincipal.Current.HasClaim() or your higher level Authorization.CheckAccess() function to validate sections of your WinForm logic.
Hope this helps :)
We may never know why Microsoft decided to limit developers by making HealthVault applications constrained to a single web/app.config entry for a HealthVault application. However I need to be able to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
I won’t go into the details of the reasoning behind 2 different HealthVault applications, but other than to say we need it to work. I still cannot login correctly with MSDN Forums (think infinite redirection sign in loop) so I am hoping for a post here that will help me.
I did contact a HealthVault developer on how to achieve this however the developer gave a suggestion that I don’t believe would be reliable (if I’m wrong let me know).
The developer’s suggestion was to do the following in code when you needed to connect to HealthVault, but prior to connecting:
ConfigurationSettings.AppSettings[“ApplicationId”] = “[YOUR APP ID]”;
The problem is that this is a static property and I do see this as an issue as our web application will have different users accessing both HealthVault applications at the same time.
Does anyone have any suggestions to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
There is a way to dynamically switch app ids on runtime. Both applications must be created, both certificates must be installed. Few things to keep in mind. For every authenticated connection, user will be granted a token (aka wctoken). This token is consumed when user is redirect back from Live ID (in case live id is used...) by your redirect.aspx page (assuming your redirect page inherits from HealthServiceActionPage.This means that everytime you switch applications, you must redirect user back to Live ID with new app id to receive new token.
Here is code sample that can be user to dynamically change settings:
public class ConfigurationManager : HealthWebApplicationConfiguration
{
private string appid;
public ConfigurationManager(string appid)
{
this.appid = appid;
}
public override Guid ApplicationId
{
get
{
return AppManager.Current.GetCurrentAppId(this.appid);
}
}
}
public class AppManager
{
private static readonly Object lck = new Object();
public Guid? App;
public static AppManager Current
{
get
{
AppManager mgr = null;
if (_current == null)
{
lock (lck)
{
mgr = new AppManager();
}
}
return mgr;
}
}
private static AppManager _current;
public Guid GetCurrentAppId(string id)
{
return new Guid(id);
}
}
Usage:
ConfigurationManager cm = new ConfigurationManager(your-app-id-here);
HealthWebApplicationConfiguration.Current = cm;
I'm getting Google analytics using Google API. In order to get analytics I need to provide profile Id which looks like "ga:12345678".
The problem is that user can have many profiles. Is it possible to figure out profile Id from say Google tracking code (e.g. if I know tracking ID which looks like "UA-1234567-1")?
Are they related to each other at all?
Thanks
I had the same issue and I find out the simplest way to get google analytics profile id.
Log into Google Analytics
1.Access your site’s profile (get to the dashboard)
2.Your URL should look like:
https://www.google.com/analytics/web/#report/visitors-overview/a1234b23478970p987654/
/a1234b23478970p987654/
That last part, after the “p” is your Google Analytics Profile ID, in this case (this is a fake account) it is “987654”
You can programatically get the profiles that exist for a given WebPropertyId (UA code) using the management API (link below).
The HTTP call you make will look like this:
https://www.google.com/analytics/feeds/datasources/ga/accounts/[accountID]/webproperties/[webPropertyID]/profiles
Where accountID and webPropertyID will either be set to the specific values you are interested in or ~all to bring back everything the current user has access to.
If by convention you don't create multiple profiles under a Web Property then only the default profile will be returned for a given WebPropertyId, which means you will be getting a one-to-one mapping from WebPropertyId to profile id. This will allow you to look up a profile id from a WebPropertyId.
See here on the management API docs for more info: http://code.google.com/apis/analytics/docs/mgmt/mgmtFeedReference.html
I had just done this task of finding the profile ID by Tracking Code in Java. The key is that tracking code is used as web property Id and the profile is linked with web property through an internal web property id. So the steps are as below:
In Google developer console, set up a Service Accounts Client ID to get client email address, client Id and p12 file. Download the p12 and put to your server.
Authorize your Google Analytics account with client id and p12 file to obtain Analytics object
With Analytics object, you can obtain all web property objects, select the property with your tracking code as web property id and get its internal web property id
With Analytics object, iterate through all profile objects, select the profile which has internal web property id the same as obtained from step 2
The full code is as follows, the getProfileId() method will return the profile id you want:
import java.io.File;
import java.util.Arrays;
import org.apache.commons.lang.StringUtils;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.analytics.Analytics;
import com.google.api.services.analytics.AnalyticsScopes;
import com.google.api.services.analytics.model.Profile;
import com.google.api.services.analytics.model.Profiles;
import com.google.api.services.analytics.model.Webproperties;
import com.google.api.services.analytics.model.Webproperty;
public class AnalyticsUtils {
public static final String APP_NAME = "<YOUR APP NAME>";
public static final String CLIENT_ID = "<YOUR CLIENT ID>";
public static final String CLIENT_EMAIL = "<YOUR CLIENT EMAIL>";
public static final String PATH_TO_P12= "<PATH TO YOUR P12 FILE>";
public static final String TRACKING_ID="<YOUR TRACKING CODE>";
public static Analytics initializeAnalytics() throws Exception {
final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
final JsonFactory JSON_FACTORY = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(CLIENT_EMAIL)
.setServiceAccountPrivateKeyFromP12File(new File(PATH_TO_P12))
.setServiceAccountScopes(
Arrays.asList(AnalyticsScopes.ANALYTICS_READONLY))
.build();
Analytics analytics = new Analytics.Builder(HTTP_TRANSPORT,
JSON_FACTORY, credential).setApplicationName(APP_NAME).build();
return analytics;
}
public static String getProfileId(Analytics analytics) throws Exception {
Webproperties webproperties = analytics.management().webproperties().list("~all").execute();
String internalPropertyId = StringUtils.EMPTY;
for (Webproperty webproperty: webproperties.getItems()) {
if (TRACKING_ID.equalsIgnoreCase(webproperty.getId())) {
internalPropertyId = webproperty.getInternalWebPropertyId();
break;
}
}
Profiles profiles = analytics.management().profiles()
.list("~all", "~all").execute();
for (Profile profile: profiles.getItems()) {
if (internalPropertyId.equalsIgnoreCase(profile.getInternalWebPropertyId())) {
return profile.getId();
}
}
return StringUtils.EMPTY;
}
}
What you're trying to obtain is called the tableId. The ID used in tracking code is called the webPropertyId. It's possible to create multiple profiles, with unique tableId's, for each web property.
You can get the tableId from the "Analytics Settings > Profile Settings" screen within GA (press 'edit' on one of the profiles). Then take the "Profile ID" field and append it to "ga:". You can also download the account details, including profile data, using the Account Feed: http://code.google.com/intl/en/apis/analytics/docs/gdata/gdataReferenceAccountFeed.html
I done this using Perl.
This is the url to get request
my $ url = qq~https://www.googleapis.com/analytics/v3/management/accounts/ACCOUNTID/webproperties/WEBPROPERTYID/profiles?key=APIKEY~;
use this url with Token to generate Data where you will find the ga id
Hope this helps.
Is there any good way of combining ASP.NET Windows Authentication with a custom IPrincipal/IIdentity object? I need to store the user's email address and have done so for Forms Authentication using a custom IIdentity/IPrincipal pair that I added to the Context.CurrentUser during the AuthenticateRequest event.
How would I best go by to accomplish this using WindowsAuthentication?
Maybe you could create your "ExtendedWindowsPrincipal" as a derived class based on WindowsPrincipal, and just add your extra data to the derived class?
That way, your ExtendedWindowsPrincipal would still be recognized anywhere where a WindowsPricinpal is needed.
OR: since you're talking about using Windows Authentication, you're probably in a Windows network - is there an Active Directory or a user database somewhere, where you could look up your e-mail address that you're interested in instead of storing it in the principal?
Marc
I ended up refactoring my initial solution into replacing the Principal instead of the Identity as I originally thought. Replacing the Identity proved troublesome, since i ran into security problems when creating an instance of a new extended WindowsPrincipal.
public class ExtendedWindowsPrincipal : WindowsPrincipal
{
private readonly string _email;
public ExtendedWindowsPrincipal(WindowsIdentity ntIdentity,
string email) : base(ntIdentity)
{
_email = email;
}
public string Email
{
get { return _email; }
}
}
In my Authentication module i replaced the principal on the HttpContext like this:
var currentUser = (WindowsIdentity)HttpContext.Current.User.Identity;
HttpContext.Current.User =
new ExtendedWindowsPrincipal(currentUser, userEmail);