我在这里发布了一些更多的补充信息,以供任何可能在这个问题上挣扎的人想要从像UWP或Xamarin这样的客户端访问MVC5/Web Api 2,但您需要使用Authorize属性锁定Web Api的区域。
高级别的过程不是通过任何MVC控制器,而是直接向/ Token端点(或任何指定的端点)执行POST。
第一件事,第一,如果你想要做发展SSL,但没有一个证书呢,继续前进,运行以下命令:
C:\Program Files (x86)\IIS Express>iisexpressadmincmd setupSslUrl -url:https://localhost:55970/ -UseSelfSigned
其中55970是无论是本地网站端口的端口是的,我将在我的文本中提到这一点。
接下来要做的事情是确保并覆盖ApplicationOAuthProvider.cs上的客户端验证和资源授予方法,否则会遇到无效的客户端或无效的授予错误。
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
UserManager<ApplicationUser> _userManager;
ApplicationDbContext db = new ApplicationDbContext();
_userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
try
{
ApplicationUser user = await _userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("role", "user"));
context.Validated(identity);
}
catch (Exception ex)
{
string str = ex.ToString();
}
db.Dispose();
}
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId = "";
string clientSecret = "";
context.TryGetFormCredentials(out clientId, out clientSecret);
List<string> validClients = new List<string>(){ "web","Alliance_UWP","Alliance_Xamarin","Alliance_Web" };
if (validClients.Contains(clientId))
context.Validated();
}
你并不需要像冗长,因为我是在允许的客户,只是“网”是好的,你会包括在你的HTTP POST方法作为一个URL编码形式值,沿用grant_type =“密码”和你的用户名/密码。这里有一个我写的快速而脏的UWP客户端,它只需要输入用户名/密码,并通过api绑定的Authorize属性访问我所拥有的数据集。如果你不认证你会得到一个授权错误,这正是我们想要的。
这里只需要注意,在我的客户端中,我过滤掉了自签名证书错误,因为我通过上述命令在IIS Express中设置了自签名证书。
Uri tokenUri = new Uri(@"https://localhost:55970/Token");
// This is a test data set from my Web Api pulling data from
// Entity Framework and SQL Server protected by the Authorize attribute
Uri testCasesUri = new Uri(@"https://localhost:55970/api/Cases");
string accessToken = "";
public MainPage()
{
this.InitializeComponent();
}
private async void btn_SubmitLogin_Click(object sender, RoutedEventArgs e)
{
string username = txt_User.Text;
string password = txt_Password.Password;
HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationFailure);
HttpClient client = new HttpClient(filter);
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("client_id", "web");
parameters.Add("grant_type", "password");
parameters.Add("username", username);
parameters.Add("password", password);
try
{
HttpResponseMessage result = await client.PostAsync(tokenUri, new HttpFormUrlEncodedContent(parameters));
string jsonResult = await result.Content.ReadAsStringAsync();
// TokenResult is a custom model class for deserialization of the Token Endpoint
// Be sure to include Newtonsoft.Json from NuGet
var resultObject = JsonConvert.DeserializeObject<TokenResult>(jsonResult);
accessToken = resultObject.AccessToken;
// When setting the request for data from Web Api set the Authorization
// header to Bearer and the token you retrieved
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
result = await client.GetAsync(testCasesUri);
jsonResult = await result.Content.ReadAsStringAsync();
} catch(Exception ex)
{
string debugBreak = ex.ToString();
}
希望能帮助你们任何一个人在Xamarin或UWP使用Web Api时遇到麻烦。
那么约翰,你是如何将授权令牌从客户端发送到授权操作的?无论是哪个客户端,MVC或UWP或Javascript客户端,您需要使用HttpClient(MVC,UWP)或使用ajax,jquery等将Authorization标头中的标记发送到您的api,如果javascript客户端 – Jinish
您可以测试您的授权端点使用代理工具(如邮递员或Fiddler)创建请求时,添加带有令牌的授权标头 – Jinish
所以现在在我的UWP应用程序中,我在/ Account/Login上进行GET,以便首先获取页面我可以获得防伪标记。我通过Regex解析了这个问题,因为我很难在UWP中找到一个Html DOM库(没有去第三方),除非我找错了位置。在那一点上,我仍然需要得到一个不记名的令牌,我想用Authorize命中Web API,但我不知道该怎么做。 –