如何生成令牌来查询REST ArcGIS服务
本文关键字:REST ArcGIS 服务 查询 何生成 令牌 | 更新日期: 2023-09-27 18:06:59
我有一个。net应用程序需要访问REST ArcGIS服务。此服务是私有的,需要基于令牌的身份验证才能访问服务中的数据。由于我是ArcGIS的新手,所以我不知道如何生成令牌并在我的。net应用程序中使用它。
看一下Esri的代理是如何获得令牌的:https://developers.arcgis.com/authentication/working-with-proxies/
特别是:https://github.com/Esri/resource-proxy/tree/master/DotNethttps://github.com/Esri/resource-proxy/blob/master/DotNet/proxy.ashx
正如@spiskula所提到的,您可以遵循https://github.com/Esri/resource-proxy/blob/master/DotNet/proxy.ashx中所示的方法,特别是getNewTokenIfCredentialsAreSpecified方法。
这里有一个非常简单的例子(在。net 4.5之前),在没有SDK的情况下做同样的事情。用户将需要通过错误处理等使其更健壮。
private string GetToken()
{
var request = (HttpWebRequest)WebRequest.Create("https://www.arcgis.com/sharing/rest/oauth2/token/");
var postData = "client_id=yourclientid"; //required
postData += "&client_secret=yourclientsecret"; //required
postData += "&grant_type=client_credentials"; //required
postData += "&expiration=120"; //optional, default
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
ESRITokenResponse eToken = Newtonsoft.Json.JsonConvert.DeserializeObject<ESRITokenResponse>(responseString);
return eToken.access_token;
}
public class ESRITokenResponse
{
public string access_token { get; set; }
public string expires_in { get; set; }
}
如果您想要简单的http
请求,您可以创建一个简单的连接,如下所示。
首先,您必须知道生成令牌url。例如,如果服务器url
是http://myserver/arcgis/rest/services ....
您的生成令牌url
是:http://myserver/arcgis/tokens/generateToken.
public class ArcgisTokenResponseModel
{
public string token { get; set; }
public string expires { get; set; }
}
对于可重用代码,我们可以创建一个准备querystring键值的类。这个类看起来就像下面的代码:
public class TokenModel
{
public string f { get; set; }
public string username { get; set; }
public string password { get; set; }
public string ip { get; set; }
public int expiration { get; set; }
public string client { get; set; }
public TokenModel(string username, string password, string ip, int expiration, string f = "json")
{
this.expiration = expiration;
this.f = f;
this.ip = ip;
this.password = password;
this.username = username;
}
public string GetQueryStringParameter()
{
return "f=" + this.f + "&username=" + this.username + "&password=" + this.password + "&ip=" + this.ip + "&expiration=" + this.expiration;
}
}
然后编写一个函数,从ArcGis
服务器生成带有用户名和密码的令牌。这个函数可能像这样:
protected string GetToken(string generateTokenUrl,string username,string password)
{
try
{
string ipadress = _serverInformationHelper.GetIPAddress();
int exp = 60;
if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
{
Model.Arcgis.TokenModel tokenModel = new Model.Arcgis.TokenModel(username, password, ipadress, exp);
//token bilgisinin alınacağı server url'i
string post = tokenModel.GetQueryStringParameter();
WebClient clientToken = new WebClient();
clientToken.Headers.Add("Content-Type: application/x-www-form-urlencoded");
string tokenResult = clientToken.UploadString(generateTokenUrl, post);
ArcgisTokenResponseModel resultTokenModel = _seriliazer.Deserialize<ArcgisTokenResponseModel>(tokenResult);
if (resultTokenModel != null && !string.IsNullOrEmpty(resultTokenModel.token))
return resultTokenModel.token;
}
return null;
}
catch (Exception ex)
{
return null;
}
}
毕竟,无论你想要什么,你都可以使用GetToken()函数
在ArcGIS pro插件中,
- 创建ArcGIS服务令牌
var url = "https://{baseUrl}/arcgis/tokens/generateToken";
var request = (HttpWebRequest)WebRequest.Create(url);
var postData = "f=JSON";
postData += "&username={username}";
postData += "&password={password}";
postData += "&client=ip";
postData += "&ip=" + GetLocalIP();
postData += "&expiration=60";
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var resString = new StreamReader(response.GetResponseStream()).ReadToEnd();
return (EsriToken)new JavaScriptSerializer().Deserialize(resString, typeof(EsriToken));
EsriToken是一个有两个属性的类:
public class EsriToken
{
public string token { get; set; }
public string expire { get; set; }
}
- 在应用程序cookie中为服务url设置令牌:
- 添加featureLayer作为安全的ArcGIS服务:
ProApp.SetCookie(new Uri("https://{baseUrl}/arcgis/services/"), "agstoken=" + token); // token is into EsriToken class...
await QueuedTask.Run(() =>
{
map = MapFactory.Instance.CreateMap(title, MapType.Map, MapViewingMode.Map, Basemap.ProjectDefault);
ServiceConnectionProperties serviceConnectionProperties = new ServiceConnectionProperties(new Uri("https://{baseUrl}/arcgis/services/{YourServicePath}"));
using (Geodatabase fs_db = new Geodatabase(serviceConnectionProperties))
{
IReadOnlyList<TableDefinition> definitions = fs_db.GetDefinitions<FeatureClassDefinition>();
var dataset_name = "{YourDatasetNameHere}";
var fc = fs_db.OpenDataset<FeatureClass>(dataset_name);
try
{
var layer = LayerFactory.Instance.CreateFeatureLayer(fc, map);
}
catch (Exception e)
{
throw;
}
}
});
App.Panes.CreateMapPaneAsync(map);
Tadaa……好啦!!
对不起我的英语。
参见https://developers.arcgis.com/authentication/accessing-arcgis-online-services/#using-rest了解概述。有两个选项:
- 更容易:使用ArcGIS Runtime SDK: https://developers.arcgis.com/net/desktop/guide/use-arcgis-token-authentication.htm 更难:发布你自己的令牌请求:https://developers.arcgis.com/authentication/accessing-arcgis-online-services/#using-rest(没有。net示例,可能因为你真的应该使用ArcGIS Runtime)
这是一个ArcGIS Runtime SDK for . net示例,使用硬编码登录。我上面链接的. net页面也有一个向用户询问凭据的示例。
try
{
var opts = new GenerateTokenOptions();
opts.TokenAuthenticationType = TokenAuthenticationType.ArcGISToken;
// generate an ArcGIS token credential with a hard-coded user name and password
// (if authentication fails, an ArcGISWebException will be thrown)
var cred = await IdentityManager.Current.GenerateCredentialAsync(
"http://serverapps10.esri.com/arcgis/rest/services/",
"user1",
"pass.word1",
opts);
// add the credential to the IdentityManager (will be included in all requests to this portal)
IdentityManager.Current.AddCredential(cred);
// load a layer based on a secured resource on the portal
var layer = new ArcGISDynamicMapServiceLayer(new Uri
("http://serverapps10.esri.com/arcgis/rest/services/GulfLawrenceSecureUser1/MapServer"));
await layer.InitializeAsync();
// add the layer to the map and zoom to its extent
this.MyMapView.Map.Layers.Add(layer);
await this.MyMapView.SetViewAsync(layer.FullExtent);
}
catch (ArcGISWebException webExp)
{
MessageBox.Show("Unable to authenticate with portal: " + webExp.Message);
}
catch (Exception exp)
{
MessageBox.Show("Unable to load secured layer: " + exp.Message);
}