我正在尝试将IdentityServer4与ASP.NET MVC WebAPI集成。我希望实现基于角色的授权。我有以下项目在运行。
我已经实施了 ResourceOwnerPassword 流程,我想要做的是,
对于上面的部分,我成功了,这里是代码
POSTMAN致电登录
的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中还有两个动作(仅用于测试),即:
SecureValues [返回成功并需要身份验证]
[HttpGet]
public BaseModel values()
{
return new BaseModel
{
success = true
};
}
[Authorize]
[HttpGet]
public BaseModel SecureValues()
{
return new BaseModel
{
success = true
};
}
调用&#34;值&#34; 操作会返回非常明显的成功,调用&#34; SecureValues&#34; 给出以下
这意味着用户未经过身份验证。
我的 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
});
}
答案 0 :(得分:1)
您的UseIdentityServerBearerTokenAuthentication
中间件中的权限看起来是错误的。我认为它应该是“http://localhost:5000”。
同时启用日志记录(带跟踪)到控制台,您可以看到有时为什么您的授权受到质疑。