使用 Web API 从 Angular 7 TS 到 .Net Owin 的令牌身份验证时收到错误密码

Reciving wrong password when using Web API Token Authentication from Angular 7 TS to .Net Owin

我正在使用 Angular 7 .i 将带有用户名和密码的令牌数据发送到服务器 (.net) 但是 OAuthGrantResourceOwnerCredentialsContext 收到错误的密码(不完整)

我的密码后面有'&',在'&'之前我只收到一半的密码,因为它被'&'字符截断了

例如,如果发送 '123&123abc',我将只收到 '123' in ,y context.Password.

我可以找到用 char '&' 发送密码的方法。

我做错了什么如何将带有 char '&' 的密码从 ts 发送到 .net 令牌控制器?

我的ts代码

     public login(username: string, password: string): Observable<UserLoginClaims> {
          //password='123&123abc';
 const tokenData = 'username=' + username + '&password=' + password + '&grant_type=password';
            const tokenHeaders: HttpHeaders = new HttpHeaders({ 'Content-Type': 'application/x-www-urlencoded', 'No-Auth': 'True' });

            return this.httpClient.post<UserPzToken>('http://localhost:10392/token', tokenData, { headers: tokenHeaders }).pipe(
              concatMap((userPzToken: UserPzToken) => {
                if (this.localStorageService.setItem('UserPzToken', userPzToken)) {
                  this.UserLogged = true;
                }
                return this.apiService.getItem<UserLoginClaims>('http://localhost:10392/Auth/GetUserClaims').pipe(
                  tap((userLoginClaims: UserLoginClaims) => this.localStorageService.setItem('UserLoginClaims', userLoginClaims))
                );
              }),
              catchError(this.errorHandleService.handleError)
            );
          }

我的创业公司class c#

 public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888

            //Enable Cors with OWin.
            app.UseCors(CorsOptions.AllowAll);

            OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
            {
                // Path at the url to get the token
                TokenEndpointPath = new PathString("/token"),
                // The provider we built.
                Provider = new ApplicationOAuthProvider(),
                AccessTokenExpireTimeSpan = TimeSpan.FromHours(24),
                AllowInsecureHttp = true,
            };

            app.Use<OwinExceptionHandlerMiddleware>();

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



    public class OwinExceptionHandlerMiddleware : OwinMiddleware
    {
        public OwinExceptionHandlerMiddleware(OwinMiddleware next) : base(next) { }





        public async override Task Invoke(IOwinContext context)
        {
            try
            {
                await Next.Invoke(context);
            }
            catch (Exception ex)
            {
                try
                {
                    if (ex is UserAuthException)
                    {
                        //context.Set
                        context.Response.StatusCode = 422; // Status422U nprocessable Entity
                        context.Response.ReasonPhrase = (ex as UserAuthException).ToString();
                        context.Response.ContentType = "application/json";
                    }
                    else
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ReasonPhrase = "Internal Server Error";
                        Logger.Error(ex);
                    }
                }
                catch (Exception innerEx)
                {
                    Logger.Error(innerEx);
                    throw ex;
                }

            }
        }

        private void HandleException(Exception ex, IOwinContext context)
        {
            var request = context.Request;

            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            context.Response.ContentType = "application/json";

        }

    }

我的 ApplicationOAuthProvider class c#

 public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
        {
            public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
            {
                context.Validated();
            }

            public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
            {

                string username = context.UserName;
                string password = context.Password;
                 //here password is 123 not 123&abc
              }

我的 WebApiConfig class

 public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        // Cors enabled at startup.cs file.
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Filters.Add(new AuthorizeAttribute());     
    }

我没有找到完美的解决方案,但我找到了快速简单的方法来避免密码中的字符问题。

我在发送之前用问题字符“&”编码了我的密码

 btoa(password) 

const tokenData = 'username=' +  btoa(username) + '&password=' + btoa(password) + '&grant_type=password';

我在服务器中对其进行解码

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {

            var Passwordbase64EncodedBytes = System.Convert.FromBase64String(context.Password);
            string password = System.Text.Encoding.UTF8.GetString(Passwordbase64EncodedBytes);
                   ........................
            }