webapi集成owin使用Oauth认证时能获取accee_token仍无法登录的解决办法
HttpConfiguration webapiConfig = new HttpConfiguration(); IIocBuilder iocBuilder = new OwinAutofacIocBuilder(services, app, webapiConfig); HelpPageConfig.Register(webapiConfig); //webapiConfig.EnsureInitialized(); app.UseCanDoo(iocBuilder); ConfigureAuth(app, iocBuilder.ServiceProvider); //这一行代码必须放在ConfiureOAuth(app)之后 ,就这一点,花我两天+一个通宵啊 //app.UseWebApi(config); webapiConfig.MapHttpAttributeRoutes();
//当webapi作为一owin一部分运行时,下面这两句不能有,不然除了webapi,其它程序验证不了
//webapiConfig.SuppressDefaultHostAuthentication();
//webapiConfig.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
webapiConfig.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); app.UseAutofacWebApi(webapiConfig); app.UseWebApi(webapiConfig); app.UseAutofacMvc(); webapiConfig.EnsureInitialized();
//这一行代码必须放在ConfiureOAuth(app)之后 ,操,就这一点,花我两天+一个通宵啊 //app.UseWebApi(config);
如果不放这之后,access_token正常获取与提交,但还是会不能认证,返回401
另外IAuthenticationManager注入方式要改成如下方式,webapi中没有 HttpContext
//HttpContext.Current.GetOwinContext().Authentication builder.Register(c => c.Resolve<IOwinContext>().Authentication).InstancePerLifetimeScope();
客户端测试代码
using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; namespace ResourceOwnerPasswordCredentialGrantDemo { class Program { static void Main(string[] args) { OauthTest oauthTest = new OauthTest(); oauthTest.Test(); oauthTest.Test1(); Console.ReadKey(); } } public class OauthTest { private string clientId = "123456"; private string clientSecret = "abcdef"; private HttpClient _httpClient; //private string AuthorizationServerBaseAddress= "http://localhost:44246/"; //private string myPath = "api/Values"; private string AuthorizationServerBaseAddress = "http://localhost:23426/"; private string myPath = "api/Hello/"; private string myPath1 = "api/Hello/1"; public OauthTest() { _httpClient = new HttpClient(); _httpClient.BaseAddress = new Uri(AuthorizationServerBaseAddress); } private async Task<string> GetAccessToken() { _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( "Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret))); var parameters = new Dictionary<string, string>(); //parameters.Add("client_id", clientId); //parameters.Add("client_secret", clientSecret); parameters.Add("grant_type", "client_credentials"); var response = await _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters)); var responseValue = await response.Content.ReadAsStringAsync(); //Console.WriteLine(responseValue); return JObject.Parse(responseValue)["access_token"].Value<string>(); } public async Task Test() { Console.WriteLine(); var token = GetAccessToken().Result; _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token); Console.WriteLine(await (await _httpClient.GetAsync(myPath)).Content.ReadAsStringAsync()); } private async Task<string> GetAccessToken1() { _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( "Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret))); var parameters = new Dictionary<string, string>(); parameters.Add("grant_type", "password"); parameters.Add("username", "你的账号"); parameters.Add("password", "你的密码"); var response = await _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters)); var responseValue = await response.Content.ReadAsStringAsync(); //Console.WriteLine(JObject.Parse(responseValue)["access_token"].Value<string>()); return JObject.Parse(responseValue)["access_token"].Value<string>(); } public async Task Test1() { var token = GetAccessToken1().Result; _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);//bearer Console.WriteLine(_httpClient.DefaultRequestHeaders); Console.WriteLine(await (await _httpClient.GetAsync(myPath1)).Content.ReadAsStringAsync()); } } }
fiddler申请token
发内容client_id=12456&client_secret=abcdef&grant_type=client_credentials
账号模式:
发内容:client_id=12456&client_secret=abcdef&grant_type=password&username=用户名&password=密码
请求头带token
User-Agent: Fiddler Content-Type: application/json Authorization: bearer QeI39h-vuEEVfNAOzt2bnXC9gkByLo0GvN-J64w72KJuocC42pZrZ0AB6vIYPkSUGb5tZCWd5KZ58cY-9pwaR69u1TR5j6Ek_7OJxd-KWPVeXR-rECo0lJpZFI9xVAMKIbXgpj5hFulJJpD1rGCaVbsFNp68pnAb_qPN-tBe8NIHzjdHstP30wUp6BNpHOaIsjlgbr-BxsIno55tvkimMQ
bearer后与token之间必需要有一个空格