Как получить токен доступа в Web Api OAuth?

У меня есть веб-приложение, которое создает ссылку для доступа к токену доступа к веб-API 2.

В основном, вызывается следующее действие контроллера:

GetExternalLogin at AccountController:

 ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
            externalLogin.ProviderKey));

        bool hasRegistered = user != null;

        if (hasRegistered)
        {
            Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);

            ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
               OAuthDefaults.AuthenticationType);
            ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
                CookieAuthenticationDefaults.AuthenticationType);

            AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
            Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
        }
        else
        {
      // as user is not registered, this block is hit
            IEnumerable<Claim> claims = externalLogin.GetClaims();
            ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
            Authentication.SignIn(identity);
        }

        return Ok(); 

Теперь эта строка возврата Ok просто вернется к базовому URL-адресу веб-API и добавит токен после этого:

https://localhost:44301/#access_token=iPl1MSgnjI3oXgDxuCH9_t5I1SsELUH-v_vNXdehGpNWsCWsQaX7csWWadWRq4H2uZ0BB8zZm2s0xOI8TSOfgzH7QbFVko4Ui8jM5SylhPgkC7eiQG-kChDfa5HMlxKF1JvRg9Kvs40rPGqsC22uel-Gi2QZlrMh_5M0NT06QOOMv4bDTAFljKw9clsMiHidX4TPfQ6UmhROMIo8FcBDlAfH7wZbSQZjFAWm4Mub-oMoUxUOzAVxJrjGiM9gxwk4iqLqGbcFVl6AncJnFO_YDtmWH_sRBvmbfzpQ6GiB10eyY-hA_L-sWtQbX8IPPtOKuWGbyg0_MfaWBfAJfUiNjH6_VjcOfPEdwUPEvbnR8vw&token_type=bearer&expires_in=1209600&state=Qvlzg__CCwjCjaqEOInQw0__FprOykwROuAciRgDlIQ1

и все.

Как я получаю эти параметры из URL-адреса и обрабатываю их?

Если я изменил базовый URL на любое другое действие, я получаю ошибку "invalid_request", вызванную вызовом uri, отличается от redirect_uri.

Итак, как клиентское приложение получает токен доступа?

Любая помощь или пояснение будут действительно полезны.

Ответ 1

1. создать класс для токена

public class Token  
   {  
       [JsonProperty("access_token")]  
       public string AccessToken { get; set; }  

       [JsonProperty("token_type")]  
       public string TokenType { get; set; }  

       [JsonProperty("expires_in")]  
       public int ExpiresIn { get; set; }  

       [JsonProperty("refresh_token")]  
       public string RefreshToken { get; set; }  
   } 

2. Класс запуска

   [assembly: OwinStartup(typeof(ProjectName.API.Startup))]
   namespace ProjectName.API
{
   public class Startup  
    {  
        public void Configuration(IAppBuilder app)  
        {  
            var oauthProvider = new OAuthAuthorizationServerProvider  
            {  
                OnGrantResourceOwnerCredentials = async context =>  
                {  
                    if (context.UserName == "xyz" && context.Password == "[email protected]")  
                    {  
                        var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);  
                        claimsIdentity.AddClaim(new Claim("user", context.UserName));  
                        context.Validated(claimsIdentity);  
                        return;  
                    }  
                    context.Rejected();  
                },  
                OnValidateClientAuthentication = async context =>  
                {  
                    string clientId;  
                    string clientSecret;  
                    if (context.TryGetBasicCredentials(out clientId, out clientSecret))  
                    {  
                        if (clientId == "xyz" && clientSecret == "secretKey")  
                        {  
                            context.Validated();  
                        }  
                    }  
                }  
            };  
            var oauthOptions = new OAuthAuthorizationServerOptions  
            {  
                AllowInsecureHttp = true,  
                TokenEndpointPath = new PathString("/accesstoken"),  
                Provider = oauthProvider,  
                AuthorizationCodeExpireTimeSpan= TimeSpan.FromMinutes(1),  
                AccessTokenExpireTimeSpan=TimeSpan.FromMinutes(3),  
                SystemClock= new SystemClock()  

            };  
            app.UseOAuthAuthorizationServer(oauthOptions);  
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());  

            var config = new HttpConfiguration();  
            config.MapHttpAttributeRoutes();  
            app.UseWebApi(config);  
        }  
    }  
}

3. Добавьте контроллер

[Authorize]  
   public class TestController : ApiController  
   {  
       [Route("test")]  
       public HttpResponseMessage Get()  
       {  
           return Request.CreateResponse(HttpStatusCode.OK, "hello !");  
       }  
   }  

4. Теперь проверьте авторизацию на основе токена

static void Main()  
       {  
           string baseAddress = "http://localhost:/";  

           // Start OWIN host     
           using (WebApp.Start<Startup>(url: baseAddress))  
           {  
               var client = new HttpClient();  
               var response = client.GetAsync(baseAddress + "test").Result;  
               Console.WriteLine(response);  

               Console.WriteLine();  

               var authorizationHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes("xyz:secretKey"));  
               client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authorizationHeader);  

               var form = new Dictionary<string, string>  
               {  
                   {"grant_type", "password"},  
                   {"username", "xyz"},  
                   {"password", "[email protected]"},  
               };  

               var tokenResponse = client.PostAsync(baseAddress + "accesstoken", new FormUrlEncodedContent(form)).Result;  
               var token = tokenResponse.Content.ReadAsAsync<Token>(new[] { new JsonMediaTypeFormatter() }).Result;  

               Console.WriteLine("Token issued is: {0}", token.AccessToken);  

               Console.WriteLine();  

               client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);  
               var authorizedResponse = client.GetAsync(baseAddress + "test").Result;  
               Console.WriteLine(authorizedResponse);  
               Console.WriteLine(authorizedResponse.Content.ReadAsStringAsync().Result);  
           }  


       }