将IdentityServer4与WebAPI集成

时间:2016-12-13 07:07:13

标签: asp.net-mvc asp.net-web-api oauth-2.0 identityserver3 identityserver4

我正在尝试将IdentityServer4与ASP.NET MVC WebAPI集成。我希望实现基于角色的授权。我有以下项目在运行。

  1. IdentityServer4 [单独的项目]
  2. WebApi
  3. Javascript Application [using Extjs]
  4. 我已经实施了 ResourceOwnerPassword 流程,我想要做的是,

    1. 向包含用户名和密码的WebApi的 AccountController 发出发布请求
    2. 在AccountController内部调用IdentityServer令牌端点以获取访问令牌并将访问令牌返回给客户端(javascript app)
    3. 向包含访问令牌的WebApi发出请求。
    4. 对于上面的部分,我成功了,这里是代码

      POSTMAN致电登录

      enter image description here

      的AccountController

       [ActionName("Login")]
          [AllowAnonymous]
          [HttpPost]
          public async Task<BaseModel> Login(LoginModel model)
          {
              model.RememberMe = false;
              var status = await _security.Login(model.Email, model.Password, model.RememberMe);
      
              if (status.Status == LoginStatus.Succeded)
              {
                  return new BaseModel { success = true, message = "login", data = status.Data };
              }
          }
      

      SecurityService

        public async Task<LoginResponse> Login(string userName, string password, bool persistCookie = false)
          {
              // discover endpoints from metadata
              var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
      
              // request token
              var tokenClient = new TokenClient(disco.TokenEndpoint, "ro.client", "secret");
              var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync(userName, password, "api1");
      
              if (tokenResponse.IsError)
              {
                  return new LoginResponse { Status = LoginStatus.Failed, Message = tokenResponse.Error };
              }
      
              return new LoginResponse { Status = LoginStatus.Succeded, Data = tokenResponse.Json };
          }
      

      安全API

      我在AccountController中还有两个动作(仅用于测试),即:

      1. values()[返回成功并且不需要身份验证]
      2. SecureValues [返回成功并需要身份验证]

        [HttpGet]
        public BaseModel values()
        {
            return new BaseModel
            {
                success = true
            };
        }
        
        [Authorize]
        [HttpGet]
        public BaseModel SecureValues()
        {
            return new BaseModel
            {
                success = true
            };
        }
        
      3. 调用&#34;值&#34; 操作会返回非常明显的成功,调用&#34; SecureValues&#34; 给出以下

        enter image description here

        这意味着用户未经过身份验证。

        我的 IdentityServer4 配置如下:

         public class Config
        {
            // scopes define the resources in your system
            public static IEnumerable<Scope> GetScopes()
            {
                return new List<Scope>
                {
                    StandardScopes.OpenId,
                    StandardScopes.Profile,
        
                    new Scope
                    {
                        Name = "api1",
                        Description = "My API",
                        DisplayName = "API Access",
                        Type = ScopeType.Resource,
                        IncludeAllClaimsForUser = true,
                        Claims = new List<ScopeClaim>
                        {
                            new ScopeClaim(ClaimTypes.Name),
                            new ScopeClaim(ClaimTypes.Role)
                        }
                    },
                   new Scope
                   {
                       Enabled = true,
                       Name  = "role",
                       DisplayName = "Role(s)",
                       Description = "roles of user",
                       Type = ScopeType.Identity,
                       Claims = new List<ScopeClaim>
                       {
                           new ScopeClaim(ClaimTypes.Role,false)
                       }
                   },
                   StandardScopes.AllClaims
                };
            }
        
            // clients want to access resources (aka scopes)
            public static IEnumerable<Client> GetClients()
            {
                // client credentials client
                return new List<Client>
                {
                    new Client
                    {
                        ClientId = "client",
                        AllowedGrantTypes = GrantTypes.ClientCredentials,
        
                        ClientSecrets =
                        {
                            new Secret("secret".Sha256())
                        },
                        AllowedScopes = { "api1" }
                    },
        
                    // resource owner password grant client
                    new Client
                    {
                        ClientId = "ro.client",
                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
        
                        ClientSecrets =
                        {
                            new Secret("secret".Sha256())
                        },
                        AllowedScopes = { "api1" }
                    },
        
                    // OpenID Connect implicit flow client (MVC)
                    new Client
                    {
                        ClientId = "mvc",
                        ClientName = "MVC Client",
                        AllowedGrantTypes = GrantTypes.Implicit,
        
                        //flow
        
                        RedirectUris = { "http://localhost:5002/signin-oidc" },
                        PostLogoutRedirectUris = { "http://localhost:5002" },
        
                        AllowedScopes =
                        {
                            StandardScopes.OpenId.Name,
                            StandardScopes.Profile.Name,
                            "role"
                        }
                    },
                    //for hybrid flow
                    new Client
                    {
                        ClientId = "mvchybrid",
                        ClientName ="mvc hybrid client",
                        AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                        ClientSecrets =
                        {
                            new Secret("secret".Sha256())
                        },
        
                        RedirectUris = {"http://localhost:5003/signin-oidc"},
                        PostLogoutRedirectUris = {"http://localhost:5003"},
        
                        AllowedScopes =
                        {
                            StandardScopes.OpenId.Name,
                            StandardScopes.Profile.Name,
                            StandardScopes.OfflineAccess.Name,
                            "api1"
                        }
                    },
                    new Client
                    {
                        ClientId = "js",
                        ClientName = "javascript client",
                        AllowedGrantTypes = GrantTypes.Implicit,
                        AllowAccessTokensViaBrowser= true,
                        RedirectUris = {"http://localhost:5004/callback.html"},
                        PostLogoutRedirectUris = {"http://localhost:5004/index.html"},
                        AllowedCorsOrigins = {"http://localhost:5004"},
        
                        AllowedScopes =
                        {
                            StandardScopes.OpenId.Name,
                            StandardScopes.Profile.Name,
                            "api1",
                            "role",
                            StandardScopes.AllClaims.Name
                        }
                    },
                    //aspnet identity client
                    new Client
                    {
                        ClientId = "mvcIdentity",
                        ClientName = "Mvc Identity Client",
                        AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                        RequireConsent = false,
                        ClientSecrets =
                        {
                            new Secret("secret".Sha256())
                        },
                        RedirectUris = {"http://localhost:5005/signin-oidc"},
                        PostLogoutRedirectUris = {"http://localhost:5005"},
                        AllowedScopes =
                        {
                             StandardScopes.OpenId.Name,
                             StandardScopes.Profile.Name,
                             StandardScopes.OfflineAccess.Name,
                             "api1"
                        }
                    }
                };
            }
        
            public static List<InMemoryUser> GetUsers()
            {
                return new List<InMemoryUser>
                {
                    new InMemoryUser
                    {
                        Subject = "1",
                        Username = "alice@yahoo.com",
                        Password = "password",
        
                        Claims = new List<Claim>
                        {
                            new Claim("name", "Alice"),
                            new Claim("website", "https://alice.com"),
                            new Claim(ClaimTypes.Role,"FreeUser")
                        }
                    },
                    new InMemoryUser
                    {
                        Subject = "2",
                        Username = "bob@yahoo.com",
                        Password = "password",
        
                        Claims = new List<Claim>
                        {
                            new Claim("name", "Bob"),
                            new Claim("website", "https://bob.com"),
                            new Claim(ClaimTypes.Role,"PaidUser")
                        }
                    }
                };
            }
        }
        

        WebApi配置

         public void ConfigureAuth(IAppBuilder app)
            {
        
                app.UseIdentityServerBearerTokenAuthentication(new IdentityServer3.AccessTokenValidation.IdentityServerBearerTokenAuthenticationOptions
                {
                    Authority = "localhost:5000",
                    RequiredScopes = new[] { "api1" },
                    ClientId = "ro.client",
                    ClientSecret = "secret",
                    PreserveAccessToken = true
                });
               }
        

1 个答案:

答案 0 :(得分:1)

您的UseIdentityServerBearerTokenAuthentication中间件中的权限看起来是错误的。我认为它应该是“http://localhost:5000”。

同时启用日志记录(带跟踪)到控制台,您可以看到有时为什么您的授权受到质疑。