• ASP.NET WebAPI 集成 Swagger 启用 OAuth 2.0 配置问题


    在 ASP.NET WebAPI 集成 Swagger 后,由于接口使用了 IdentityServer 做的认证,调试起来很不方便;看了下 Swashbuckle 的文档 ,是支持 OAuth2.0 的配置的,使用的简化模式(Implicit grant type),交互的流程如下:

    Implicit Grant Type (简化模式)

    参数:

    • response_type:表示授权类型,此处的值固定为"token",必选项。
    • client_id:表示客户端的ID,必选项。
    • redirect_uri:表示重定向的URI,可选项。
    • scope:表示权限范围,可选项。
    • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
        GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
            &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
        Host: server.example.com

    认证服务器回应客户端的URI,包含以下参数:

    • access_token:表示访问令牌,必选项。
    • token_type:表示令牌类型,该值大小写不敏感,必选项。
    • expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
    • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
    • state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。

         HTTP/1.1 302 Found
         Location:
    http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
                   &state=xyz&token_type=example&expires_in=3600

    Swagger 启用 OAuth 2.0 配置

    Idrv 中配置客户端(Client)

    new Client
                    {
                        ClientName = "Test_API_Flow",
                        ClientId = "api_test_api_flow",
                        Flow = Flows.Implicit,
                        ClientUri = "https://identityserver.io",
                        RequireConsent = true,
                        AllowRememberConsent = true,
                        RedirectUris = new List<string>
                        {
                            "http://localhost:39106/swagger/ui/o2c-html",
                        },
                        AllowedCorsOrigins = new List<string>
                        {
                            "http://localhost:39106"
                        },
                        AccessTokenLifetime = 3600,
                        AccessTokenType = AccessTokenType.Jwt,
                        AllowAccessToAllScopes=true
                    },

    API:

       app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
                {
                    Authority = IdsvSetting.Authority,
                    ValidationMode = ValidationMode.ValidationEndpoint,
                    RequiredScopes=new List<string> {"all","user","order"}} 
                });
        /// <summary>
        /// 早餐控制器
        /// </summary>
        [RoutePrefix("api/v1/breakfast")]
        public class BreakfastController : ApiController
        {
            private static readonly Logger logger = LogManager.GetCurrentClassLogger();
    
            /// <summary>
            /// 早餐服务
            /// </summary>
            private readonly IBreakfastService _breakfastService;
    
            /// <summary>
            /// 构造方法
            /// </summary>
            /// <param name="breakfastService">早餐服务</param>
            public BreakfastController(IBreakfastService breakfastService)
            {
                _breakfastService = breakfastService;
            }
    
            #region 获得酒店关联的餐厅的酒店
            /// <summary>
            /// 获得酒店关联的餐厅的酒店
            /// </summary>
            /// <param name="hotelcd">酒店编号</param>
            /// <returns>获得酒店关联的餐厅的酒店</returns>
            [Authorize]
            [HttpGet]
            [Route("{hotelcd}/mapping")]
            public async Task<IHttpActionResult> GetXhotelBreakfastHotelMappingRequest(string hotelcd)
            {
                var response = await _breakfastService.GetXhotelBreakfastHotelMappingRequest(hotelcd);
                return Json(response);
            }
            #endregion
        }
    }

    配置 SwaggerConfig

       //https://tsso.xxx.cn/connect/authorize?response_type=token&redirect_uri=http%3A%2F%2Flocalhost%3A39106%2Fswagger%2Fui%2Fo2c-html&realm=test-realm&client_id=api_test_api_flow&scope=all%20%20&state=oauth2
                            c.OAuth2("oauth2")
                                .Description("OAuth2 Implicit Grant")
                                .Flow("implicit")
                                .AuthorizationUrl("https://tsso.xxx.cn/connect/authorize")
                                //.TokenUrl("https://sso.xxx.cn/connect/token")
                                .Scopes(scopes =>
                                {
                                    scopes.Add("all", "all access to protected resources");
                                    scopes.Add("user", "user access to protected resources");
                                    scopes.Add("order", "order access to protected resources");
                                });
    ...   

    c.OperationFilter<AssignOAuth2SecurityRequirements>(); c.EnableOAuth2Support( clientId:
    "api_test_api_flow", clientSecret: null, realm: "test-realm", appName: "Swagger UI" //additionalQueryStringParams: new Dictionary<string, string>() { { "foo", "bar" } } );
     public class AssignOAuth2SecurityRequirements : IOperationFilter
            {
                public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
                {
                    var actFilters = apiDescription.ActionDescriptor.GetFilterPipeline();
                    var allowsAnonymous = actFilters.Select(f => f.Instance).OfType<OverrideAuthorizationAttribute>().Any();
                    if (allowsAnonymous)
                        return; // must be an anonymous method
                    //var scopes = apiDescription.ActionDescriptor.GetFilterPipeline()
                    //    .Select(filterInfo => filterInfo.Instance)
                    //    .OfType<AllowAnonymousAttribute>()
                    //    .SelectMany(attr => attr.Roles.Split(','))
                    //    .Distinct();
                    if (operation.security == null)
                        operation.security = new List<IDictionary<string, IEnumerable<string>>>();
    
                    var oAuthRequirements = new Dictionary<string, IEnumerable<string>>
                                            {
                                                {"oauth2", new List<string> {"all","user","order"}}
                                            };
    
                    operation.security.Add(oAuthRequirements);
                }
            }

    OK ,配置完成,点击红色的圈圈,登录成功会302到  http://localhost:39106/swagger/ui/o2c-htm

    image

    当然也可以退出授权:

    image

    REFER:

    https://www.scottbrady91.com/Identity-Server/ASPNET-Core-Swagger-UI-Authorization-using-IdentityServer4
    https://stackoverflow.com/questions/33752900/enable-oauth2-client-credentials-flow-in-swashbuckle
    https://stackoverflow.com/questions/29275499/swagger-swashbuckle-oauth2-with-resource-owner-password-credentials-grant?rq=1
    http://knowyourtoolset.com/2015/08/secure-web-apis-with-swagger-swashbuckle-and-oauth2-part-2/

  • 相关阅读:
    搜狗输入法赏析
    第二次冲刺个人总结05
    程序员的自我修养阅读笔记01
    第十五周学习总结
    mysql 查询优化
    mysql explain 详解
    nginx基本配置与参数说明
    input输入框实现联想关键词功能
    JS图片懒加载
    mysql中timestamp,datetime,int类型的区别与优劣
  • 原文地址:https://www.cnblogs.com/Irving/p/7275065.html
Copyright © 2020-2023  润新知