Manage AzureSearch via (Rest) API - rest

I’m trying to create a tool which should scale the „Replicas“ and „Partitions“ of an Azure Search component.
For that, I read the following article from Microsoft:
https://learn.microsoft.com/en-us/rest/api/
Right now, I am having trouble authenticating against azure to get an AuthToken.
Is there a way to do it easier? Alternatively, do you guys have a sample in how to do it?
Here is a sample of my code:
var clientId = "2aaced54873e4a94b6d5518bc815dcb1";
var redirectUri = new Uri("https://thissucks.search.windows.net");
var resource = "resource"; // What exactly should the value be?
var authContext =
new AuthenticationContext(
"https://login.windows.net/ba1cb781739c4cdea71c619ccba914e0/oauth2/authorize", new TokenCache());
var result = authContext.AcquireTokenAsync(resource, clientId, redirectUri, new PlatformParameters(PromptBehavior.Auto));
var result2 = result.Result;
After invoking this, I get an Azure Login screen. After login with valid credentials, I get the following Exception:
System.AggregateException: 'One or more errors occurred.'
InnerException:
AdalServiceException: AADSTS50001: The application named was not found in the tenant named .
This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant.
You might have sent your authentication request to the wrong tenant.

So there're a few issues in your code.
First, please make sure that you have followed the steps described here: https://learn.microsoft.com/en-us/rest/api. Once the application is created successfully, you must note down the client id of that application and use that in your code.
Next, please ensure that ba1cb781739c4cdea71c619ccba914e0 is indeed the tenant id. You could also use Azure AD domain name (something.onmicrosoft.com) instead of this GUID type value. So your URL would be https://login.windows.net/something.onmicrosoft.com/oauth2/authorize
Lastly, there are issues with the values for the following parameters:
var redirectUri = new Uri("https://thissucks.search.windows.net");
var resource = "resource"; // What exactly should the value be?
redirectUri is the URI where the Azure AD will redirect once the user is successfully authenticated. For Web Applications it is usually the URL of your website. Please make sure that it matches with the value you provided when creating an application in Azure AD. When Azure AD redirects the user to this URL, it passes a JWT token in code query string parameter using which you get access/refresh token.
resource is the resource for which you're acquiring the token. Since you want to access Resource Manager API, the value here should be https://management.core.windows.net/.

Related

What is the right way for using Azure DevOps client libraries with OAuth for long living web sessions?

We have a stateful web application that maintains long living server session for each user (as long as user works with system session is alive) that need to work with Azure DevOps. We are using .NET client libraries.
We are keeping VssConnection for the session lifetime.
We are creating connection like this:
var vssOAuthAccessTokenCredential = new VisualStudio.Services.OAuth.VssOAuthAccessTokenCredential(accessToken);
var connection = new VssConnection(connectionUrl, vssOAuthAccessTokenCredential);
The problem here is that access token expires after some time and I don’t see any kind of connection/credential class in SDK that will accept some callback that I can pass to refresh token.
I tried to implement my own IVssCredentialPrompt, but when I’m creating new VssConnection passing my IVssCredentialPrompt implementation and CredentialPromptType.PromptIfNeeded I’m getting
System.ArgumentException: The prompt option is invalid because the process is not interactive. Parameter name: PromptType.
I also can’t create my own implementation of FederatedCredential since it requires IssuedToken instance which constructor is internal.
What is recommended solution for this case?
You can use PAT token:
var credential = new VssBasicCredential(string.Empty, "PAT");
var connection = new VssConnection(new Uri("https://dev.azure.com/<your-organization>/"), credential);

WPF talking to secured web api using AutoRest

I just can't seem to get anywhere with this.
I have a web api running fine, with a wpf application using the api via AutoRest.
The api has been uploaded to Azure (App Services)
I now want to lock down the api, so users log in via Active Directory. Again, all users are currently there.
RestCredentials = new TokenCredentials(tokenAuthResult.AccessToken);
Using the RestCredentials I pass in the credentials as type
ServiceClientCredentials
using (var db = new BuxtedAPI(Model.Helpers.Credentials.RestCredentials))
{
var res = db.GetComboList();
ComboValueList = new ObservableCollection<ComboValue>(res);
return ComboValueList;
}
I can see on the log in Azure that the user successfully logs in.
But the system just dies with
Operation returned an invalid status code 'InternalServerError'
No more feedback at all.
Just to note, I am using swagger also here.
I am assuming that the BuxtedAPI call that passing the credentials should pass through the bearer token for the api call to authorise.
I have set nothing else on on webapi code base, no [AUTHORIZED] or anything.
Any chance anyone can help me along here.
Thanks Scott
If anyone else gets in this situation.
The process required Resource Id to be the web app and the clientid to be the native app id.
Scott

IdentityServer3: How to assign ClientSecret to MVC Client?

I have configured IdentityServer3 with EF and AspNetIdentity. I have 3 MVC client applications. All users and clients are configured in SQL DB. I was able to get it working and users can now log in.
Now I'm trying to add some security around Client & Users and I have few questions related
1> Does MVC client only works with Implicit Flow? I have MVC client and below is it's OWIN startup.
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "https://localhost:44314/identity",
Scope = "openid",
ClientId = "LocalHostMvcClient",
RedirectUri = "http://localhost:34937/",
ResponseType = "id_token",
SignInAsAuthenticationType = "Cookies"
});
}
}
On IdentityServer, when I change the flow of LocalHostMvcClient to any flow (Other than 'Implicit') then client get error The client application is not known or is not authorized.. So it looks like for MVC client
it only works with Implicit flow.
Is this true?
2> Is ClientSecret not relevant for Implicit flow?
I want to use ClientSecret, but looks like it is not relevant for Implicit flow. Based on documentation ClientSecret is relevant to only flows that require secret. If answer to question 1 is true then does that mean i cannot use ClientSecret with Implicit Flow?
3> If i have multiple clients and users. Can we assign a user to a particular client?
For example, if i have 3 clients, www.client1.com, www.client2.com,www.client3.com and 2 users User1,User2. I want User1 to be able to login only for www.client1.com
Is this possible?
ASP.NET MVC can use any OpenID Connect flow. The error you are receiving is due to the client application requesting something it is not allowed to or otherwise being misconfigured in some way. Enable logging in Identity Server and it'll soon tell you why.
Client Secret is not used in Implicit, as implicit relies on the requesting url, not any sort of explicit authorization. That's why it's useful for client-side languages.
This is authorization logic and should be handled within the client application. For example when they login they would be shown an 'unauthorized' page. Identity Server is for authentication only.

Throwing 404 error with the authoriseUrl generated from GetRefreshToken

I am trying to create a sample project which consumes DFP services.
Till now :
Still in authentication part :
a) Successfully created clientId, while creating new Client Id have checked installed apps options in the Google developer console.
b) Added the clientId, clientSecret to ads.properties .
Note : Took dfp-axis-jars-and-examples-2.2.0.tar and making my changes in it[by importing project in IDE].
c) I ran into trouble while trying to paste the authoriseUrl in the browser after running GetRefreshToken.
Please find below the error :
"The redirect URI in the request: urn:ietf:wg:oauth:2.0:oob can only
be used by a Client ID for native application. It is not allowed for
the 'WEB' client type. You can create a Client ID for native
application in the Credentials section of the Google Developers
Console."
I believe I have selected the wrong applicationType while creating new ClientId .
Appreciate inputs .
The above answer did not make much sense at first glance but, I have resolved this issue by simply setting a value for redirectUri. So inside of my GetRefreshToken.php file
$redirectUri = "http://same_url_as_the_one_listed_in_console";
After closing looking at the authoriseUrl, it seemed I was sending the wrong redirectUrl.
I forgot to copy paste the redirectUrl generated from the creation of client id in the GetRefreshToken callback property:
private static final String CALLBACK_URL = "https://www.example.com/oauth2callback";//"urn:ietf:wg:oauth:2.0:oob";
No error now :).

Google Data/OAuth/AppEngine/Python - Properly Registering a Web Application

I'm creating a webapp with this combination of tools. I'm authenticating with App Engine in the following manner:
class googleLogin(webapp.RequestHandler):
def get(self):
callbackURL = 'http://%s/googleLoginCallback' % getHost()
#Create a client service
gdClient = gdata.docs.service.DocsService()
gdata.alt.appengine.run_on_appengine(gdClient)
gdClient.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.HMAC_SHA1,
_GoogleConsumerKey,
consumer_secret=_GoogleConsumerSecret)
#Get a Request Token
requestToken = gdClient.FetchOAuthRequestToken(scopes=_GoogleDataScope,
extra_parameters={'xoauth_displayname': APP_NAME})
#Persist token secret
self.session = Session()
self.session[TOKENSECRETKEY] = requestToken.secret
gdClient.auto_set_current_token = True
gdClient.SetOAuthToken(requestToken)
authUrl = gdClient.GenerateOAuthAuthorizationURL(callback_url=callbackURL)
self.redirect(authUrl)
I authenticated my domain with Google at https://www.google.com/accounts/ManageDomain, entering a target URL and am using the given Consumer Key/Secret. For instance, if my domain was 'juno.appspot.com', I am using http://juno.appspot.com as the target url path prefix.
The process is working; however, Google presents this message to the user in a yellow security box:
"The application that directed you
here claims to be 'xxxxxx'. We are
unable to verify this claim as the
application runs on your computer, as
opposed to a website. We recommend
that you deny access unless you trust
the application."
I don't think I should be getting this error, since my server is getting the request token and creating the authorization URL. Does anyone have any insight on how to get rid of this warning?
Google's domain registration has an option to upload a certificate, but I shouldn't need to do that because I'm using OAuth with the HMAC_SHA1 signature method.
Also, not that it should matter, but I'm doing all this through a UIWebView on the iPhone. I'm specifically trying to do all authentication server-side to avoid exposing my Consumer Key/Secret.
Thank you for any tips :)
Solved.
The culprit is this line from above:
extra_parameters={'xoauth_displayname': APP_NAME})
Setting this value for a registered application intentionally triggers a warning to users, as indicated by the Google documentation:
xoauth_displayname:
(optional) String identifying the
application. This string is displayed
to end users on Google's authorization
confirmation page. For registered
applications, the value of this
parameter overrides the name set
during registration and also triggers
a message to the user that the
identity can't be verified. For
unregistered applications, this
parameter enables them to specify an
application name, In the case of
unregistered applications, if this
parameter is not set, Google
identifies the application using the
URL value of oauth_callback; if
neither parameter is set, Google uses
the string "anonymous".
Removing this line no longer allows me to use a 'nice' name in place of the domain, but it gets rid of that annoying yellow box :)
I'm not sure exactly where the issue may be in your code, but I've got a one page oauth/appengine/gdata example which may at least set you in the right direction. Have you tried to navigate to the site directly from the iPhone/desktop browser to see what message is delivered?
Hope it helps.
Alternatively, is it possibly to do with the user agent the UIWebView sets?