C # WebApi OWIN: код токена возвращает токен, но все обычные запросы возвращают http 400 «ошибка»: «unsupported_grant_type» - PullRequest
0 голосов
/ 07 июня 2018

У меня есть приложение odata / webapi, которое было обновлено для использования аутентификации OWIN.Код для выдачи токенов (/ token url) работает нормально и возвращает токен, но любой «нормальный» вызов любых контроллеров возвращает HTTP 400

{"error": "unsupported_grant_type"}

без дополнительной информации.

Startup.cs:

using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;
using Owin;
using System;
using System.Web.Http;

[assembly: OwinStartup(typeof(VP4C_API.Startup))]
namespace VP4C_API
{
    public class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {

            var OAuthOptions = new OAuthAuthorizationServerOptions
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new SimpleAuthorizationServerProvider()
            };

            app.UseOAuthBearerTokens(OAuthOptions);
            app.UseOAuthBearerAuthentication(oAuthBearerAuthenticationOptions);

            Statics.Config = new HttpConfiguration();
            WebApiConfig.Register(Statics.Config);

            app.UseWebApi(Statics.Config);
        }


        /// <summary>
        /// Called at when the AppPool starts the website
        /// </summary>
        /// <param name="app"></param>
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }
}

AuthorizationProvider, который возвращает токен:

using System;
using System.Threading.Tasks;
using Microsoft.Owin.Security.OAuth;
using Microsoft.Owin.Security;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;

namespace VP4C_API
{
    internal class SimpleAuthorizationServerProvider : IOAuthAuthorizationServerProvider
    {
        Task IOAuthAuthorizationServerProvider.AuthorizationEndpointResponse(OAuthAuthorizationEndpointResponseContext context)
        {
            throw new NotImplementedException();
        }

        Task IOAuthAuthorizationServerProvider.AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
        {
            throw new NotImplementedException();
        }

        Task IOAuthAuthorizationServerProvider.GrantAuthorizationCode(OAuthGrantAuthorizationCodeContext context)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Take the ClientID and validate its one we want to talk to
        /// Called after <see cref="IOAuthAuthorizationServerProvider.ValidateTokenRequest"/> /> 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        Task IOAuthAuthorizationServerProvider.GrantClientCredentials(OAuthGrantClientCredentialsContext context)
        {
            if (context.ClientId == "App1Test")
            {
                var identity = new ClaimsIdentity(new GenericIdentity(
                        context.ClientId, OAuthDefaults.AuthenticationType),
                        context.Scope.Select(x => new Claim("urn:oauth:scope", x))
                        );
                context.Validated(identity);
            }
            else
            {
                context.Rejected();
                context.SetError("Unknown client id", "You must list the client id in the known clients table");
            }
            return Task.FromResult(0);
        }

        Task IOAuthAuthorizationServerProvider.GrantCustomExtension(OAuthGrantCustomExtensionContext context)
        {
            throw new NotImplementedException();
        }

        Task IOAuthAuthorizationServerProvider.GrantRefreshToken(OAuthGrantRefreshTokenContext context)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Called after <see cref="IOAuthAuthorizationServerProvider.ValidateTokenRequest"/>
        /// Check the username/password here
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        Task IOAuthAuthorizationServerProvider.GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            if (context.UserName == "test" && context.Password == "test")
            {
                context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

                System.Security.Principal.GenericIdentity gi = new System.Security.Principal.GenericIdentity(context.UserName, OAuthDefaults.AuthenticationType);
                System.Security.Claims.ClaimsIdentity ci = new System.Security.Claims.ClaimsIdentity(gi, context.Scope.Select(x => new Claim("urn:oauth:scope", x)));
                var ticket = new AuthenticationTicket(ci, null);
                context.Validated(ticket);
            }
            else
            {
                context.SetError("GrantResourceOwner Error", "Username or Password is incorrect.");
                context.Rejected();
            }
            return Task.FromResult(0);
        }

        /// <summary>
        /// Called first to filter on the endpoint attributes (e.g. client application IP address)
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        Task IOAuthAuthorizationServerProvider.MatchEndpoint(OAuthMatchEndpointContext context)
        {
            context.MatchesTokenEndpoint();
            return Task.FromResult(0);
        }

        /// <summary>
        /// Called after <see cref="IOAuthAuthorizationServerProvider.GrantResourceOwnerCredentials"/>
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        Task IOAuthAuthorizationServerProvider.TokenEndpoint(OAuthTokenEndpointContext context)
        {
            AuthenticationProperties ap = new AuthenticationProperties();
            ap.AllowRefresh = true;
            ap.IssuedUtc = DateTime.UtcNow;
            ap.IsPersistent = true;
            context.Issue(context.Identity, ap);
            return Task.FromResult(0);
        }

        /// <summary>
        /// Called after <see cref="IOAuthAuthorizationServerProvider.TokenEndpoint"/>
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        Task IOAuthAuthorizationServerProvider.TokenEndpointResponse(OAuthTokenEndpointResponseContext context)
        {
            return Task.FromResult(0);
        }

        Task IOAuthAuthorizationServerProvider.ValidateAuthorizeRequest(OAuthValidateAuthorizeRequestContext context)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Called after <see cref="IOAuthAuthorizationServerProvider.MatchEndpoint"/>
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        Task IOAuthAuthorizationServerProvider.ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            string clientID;
            string clientPassword;
            context.TryGetBasicCredentials(out clientID, out clientPassword);
            context.Validated(clientID);
            return Task.FromResult(0);
        }

        Task IOAuthAuthorizationServerProvider.ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Called after <see cref="IOAuthAuthorizationServerProvider.ValidateClientAuthentication"/>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        Task IOAuthAuthorizationServerProvider.ValidateTokenRequest(OAuthValidateTokenRequestContext context)
        {
            context.Validated();
            return Task.FromResult(0);
        }

    }
}

и фрагмент кода контроллерадля http://host/api/Verify/1

        [HttpGet, AllowAnonymous, Route("{companyID}")]
        public IHttpActionResult Verify(int companyID)
        {
            string cs = "not set";
            int check = -1;
            try
            {
                ErrorLogging.Logging.Information(null, null, Request.RequestUri, $"Verify Start company {companyID}");

Есть предложения по поиску?

...