jwt 管理问题

来源:11-9 【应用】定制用户模型并添加初始化用户数据

weixin_慕先生4130743

2022-06-05

老师好:
请问jwt是不是一定要要使用框架提供的那些表?我没有使用原来的那些表,因为要兼容其他系统,在授权服务中通过调用存储过程,并根据结果创建了jwt,但鉴权失败,所有带[Authorize] Http Attribute 的Controller都不能访问,返回404,求助老师指点!
以下是创建jwt完整的代码。
说明:
1、其中 dataRow_UserInfo 是调用存储过程后,后台返回的用户信息,用户信息是从其他系统获取的自定义的表;
2、dataSet.Table[2] 包含了角色,loginResultDto.Token 生成的 Token 在 jwt.io中可以通过验证。

AuthenticateController 下面的一个方法部分代码

   /* Header */
                    var signingAlgorithm = SecurityAlgorithms.HmacSha256;

                    /* PayLoad */
                    var claims = new List<Claim>
                    {
                        new Claim( JwtRegisteredClaimNames.Sub, loginDto.AccountNo),
                        new Claim("UserID", dataRow_UserInfo["UserID"].ToString()),
                        new Claim("EmployeeID", dataRow_UserInfo["EmployeeID"].ToString()),
                        new Claim("PlantsNo", dataRow_UserInfo["PlantsNo"].ToString())
                        // 实际上,这里可能还有更多内容
                    };

                    foreach ( DataRow dataRow in dataSet.Tables[ 2 ].Rows )
                    {
                        string roleName = ( string )dataRow[ "RoleName" ];
                        var roleClaim = new Claim( ClaimTypes.Role, roleName );
                        claims.Add( roleClaim );
                    }

                    var secretByte = Encoding.UTF8.GetBytes( _configuration[ "Authentication:SecretKey" ] );
                    var signingKey = new SymmetricSecurityKey( secretByte );  /* 使用非对称加密算法进行加密 */
                    var signingCredentials = new SigningCredentials( signingKey, signingAlgorithm );   /* 验证加密后的私钥 */

                    var token = new JwtSecurityToken(
                        issuer: _configuration[ "Authentication:Issuer" ],
                        audience: _configuration[ "Authentication:Audience" ],
                        claims,
                        notBefore: DateTime.UtcNow,
                        expires: DateTime.UtcNow.AddDays( 1 ),
                        signingCredentials
                    );

                    loginResultDto.Token = new JwtSecurityTokenHandler( ).WriteToken( token );

以下为 Startup 类

    public class Startup
    {
        public IConfiguration Configuration { get; }

        public Startup( IConfiguration configuration )
        {
            Configuration = configuration;
        }

        readonly string CorsAllowSpecificOrigins = "_CorsAllowSpecificOrigins";

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices( IServiceCollection services )
        {

            services.AddCors( options =>  /* AddCors方法的调用会把CORS服务加到应用的服务容器中(service container); */
            {
                options.AddPolicy( CorsAllowSpecificOrigins,
                            policy =>
                            {
                               policy.AllowAnyOrigin( );
                                policy.AllowAnyHeader( );
                                policy.AllowAnyMethod( );

                           } );
            } );


            services.AddIdentity<ApplicationUser, IdentityRole>( )
                .AddEntityFrameworkStores<AppDbContext>( );

            services.AddAuthentication( JwtBearerDefaults.AuthenticationScheme )
                .AddJwtBearer( options =>
                {
                    var secretByte = Encoding.UTF8.GetBytes(Configuration["Authentication:SecretKey"]);
                    options.TokenValidationParameters = new TokenValidationParameters( )
                    {
                        ValidateIssuer = true,
                        ValidIssuer = Configuration[ "Authentication:Issuer" ],

                        ValidateAudience = true,
                        ValidAudience = Configuration[ "Authentication:Audience" ],

                        ValidateLifetime = true,

                        IssuerSigningKey = new SymmetricSecurityKey( secretByte )
                    };
                } );


            services.AddControllers( setupAction =>
            {
                setupAction.ReturnHttpNotAcceptable = true;

            } ).AddNewtonsoftJson( setupAction =>
            {
                setupAction.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver( );
            } )
            .AddXmlDataContractSerializerFormatters( )
            .ConfigureApiBehaviorOptions( setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetail = new ValidationProblemDetails(context.ModelState)
                    {
                        Type = "无所谓",
                        Title = "数据验证失败",
                        Status = StatusCodes.Status422UnprocessableEntity,
                        Detail = "请看详细说明",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetail.Extensions.Add( "traceId", context.HttpContext.TraceIdentifier );

                    return new UnprocessableEntityObjectResult( problemDetail )
                    {
                        ContentTypes = { "application/problem+json" }
                    };
                };
            } );



            services.AddDbContext<AppDbContext>( option =>
            {

                option.UseSqlServer( Configuration[ "DbContext:DevConnctionString" ] );
            } );


            // 扫描 (包含映射关系的) profile 文件
            services.AddAutoMapper( AppDomain.CurrentDomain.GetAssemblies( ) );

            services.AddHttpClient( );

            services.AddSingleton<IActionContextAccessor, ActionContextAccessor>( );

            services.Configure<MvcOptions>( config =>
            {
                var outputFormatter = config.OutputFormatters
                    .OfType<NewtonsoftJsonOutputFormatter>()?.FirstOrDefault();

                if ( outputFormatter != null )
                {
                    outputFormatter.SupportedMediaTypes
                    .Add( "application/vnd.aleks.hateoas+json" );
                }
            } );
        }


        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure( IApplicationBuilder app, IWebHostEnvironment env )
        {
            if ( env.IsDevelopment( ) )
            {
                app.UseDeveloperExceptionPage( );
            }

            // 你在哪?
            app.UseRouting( );


            app.UseCors( CorsAllowSpecificOrigins );  /* 启用跨域 */

            app.UseHttpsRedirection( );

            // 你是谁?
            app.UseAuthentication( );
            // 你可以干什么?有什么权限?
            app.UseAuthorization( );


            app.UseEndpoints( endpoints =>
            {
                endpoints.MapControllers( ).RequireCors( CorsAllowSpecificOrigins );
            } );
        }
    }

如果可以,老师也可以回复我的邮箱:chanava@139.com,谢谢!

写回答

1回答

qq_慕瓜4263387

2022-07-04

404是访问地址填错了

0
0

.Net 开发电商后端API 从0到精通RESTful

. Net 实战+RESTful思想纵深课程,开发优雅RESTful风格API。

979 学习 · 553 问题

查看课程