我安装了Windows 2012 R2附带的ADFS。我使用Windows Powershell注册了客户端并获得了client_id。我需要一个适用于带有ADFS的oAuth 2.0的示例。
非常感谢
答案 0 :(得分:0)
我是ADFS的新手,我不知道我的解决方案是否是最好的,即使我不确定它是否正确,但它对我有用。无论如何,为了以防万一,我会分享它。
基于此post,这是我使用OAuth2的ADFS自定义客户端。我的代码是使用DotNetOpenAuth的MVC4应用程序。
public class AuthServiceOAuth2Client : OAuth2Client
{
#region Constants and Fields
/// <summary>
/// The authorization endpoint.
/// </summary>
private const string AuthorizationEndpoint = "https://your_adfs/adfs/oauth2/authorize";
/// <summary>
/// The token endpoint.
/// </summary>
private const string TokenEndpoint = "https://your_adfs/adfs/oauth2/token";
/// <summary>
/// The _app id.
/// </summary>
private readonly string _clientId;
/// <summary>
/// The _app secret.
/// </summary>
private readonly string _clientSecret;
#endregion
public AuthServiceOAuth2Client(string clientId, string clientSecret)
: base("ADFS")
{
if (string.IsNullOrWhiteSpace(clientId)) throw new ArgumentNullException("clientId");
if (string.IsNullOrWhiteSpace(clientSecret)) throw new ArgumentNullException("clientSecret");
this._clientId = clientId;
this._clientSecret = clientSecret;
}
protected override Uri GetServiceLoginUrl(Uri returnUrl)
{
StringBuilder serviceUrl = new StringBuilder();
serviceUrl.AppendFormat("{0}?grant_type=authorization_code", AuthorizationEndpoint);
serviceUrl.AppendFormat("&redirect_uri={0}", returnUrl.ToString());
serviceUrl.Append("&response_type=code");
serviceUrl.AppendFormat("&client_id={0}", _clientId);
serviceUrl.AppendFormat("&resource={0}", "your_resource");
return new Uri(serviceUrl.ToString());
}
protected override IDictionary<string, string> GetUserData(string accessToken)
{
// do stuff
return new Dictionary<String, String>();
}
protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
{
StringBuilder postData = new StringBuilder();
postData.AppendFormat("client_id={0}", this._clientId);
postData.AppendFormat("&redirect_uri={0}", HttpUtility.UrlEncode(returnUrl.ToString()));
postData.AppendFormat("&client_secret={0}", this._clientSecret);
postData.AppendFormat("&grant_type={0}", "authorization_code");
postData.AppendFormat("&code={0}", authorizationCode);
string response = "";
string accessToken = "";
var webRequest = (HttpWebRequest)WebRequest.Create(TokenEndpoint);
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
try
{
using (Stream s = webRequest.GetRequestStream())
{
using (StreamWriter sw = new StreamWriter(s))
sw.Write(postData.ToString());
}
using (WebResponse webResponse = webRequest.GetResponse())
{
using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
{
response = reader.ReadToEnd();
}
}
var json = JObject.Parse(response);
accessToken = (string)json["access_token"];
}
catch (Exception ex)
{
return null;
}
return accessToken;
}
public override AuthenticationResult VerifyAuthentication(HttpContextBase context, Uri returnPageUrl)
{
string code = context.Request.QueryString["code"];
if (string.IsNullOrEmpty(code))
{
return AuthenticationResult.Failed;
}
string accessToken = this.QueryAccessToken(returnPageUrl, code);
if (accessToken == null)
{
return AuthenticationResult.Failed;
}
IDictionary<string, string> userData = this.GetUserData(accessToken);
if (userData == null)
{
return AuthenticationResult.Failed;
}
string id = userData["id"];
string name;
// Some oAuth providers do not return value for the 'username' attribute.
// In that case, try the 'name' attribute. If it's still unavailable, fall back to 'id'
if (!userData.TryGetValue("username", out name) && !userData.TryGetValue("name", out name))
{
name = id;
}
// add the access token to the user data dictionary just in case page developers want to use it
userData["accesstoken"] = accessToken;
return new AuthenticationResult(
isSuccessful: true, provider: this.ProviderName, providerUserId: id, userName: name, extraData: userData);
}
}
注意redirectUri,因为它应该与您在ADFS上注册的相同。
此外,我根据Vittorio的post编写了一个小的Web API项目来检索用户信息。
希望它有所帮助。