我目前正在使用ASP Core 1.1中的OpenIdentityServer 4。 我可以使用ResourceOwnerPassword授权类型等来授予令牌。创建我的自定义ResourcePasswordValidator等。
目前在我的测试应用程序中,我检索带有用户凭据的令牌并且所有问题都很好,但是当我尝试使用[Authorize]属性访问IdentityController时,我被重定向到未授权页面并发送了403禁用的http代码
我不确定问题是什么。我怀疑它可能来自范围/资源问题 任何帮助,无论如何。
消费者的示例代码
public class TestAuthentication
{
private HttpClient _client;
public TestAuthentication()
{
_client = new HttpClient();
}
public async Task RunTest()
{
var token = await GetToken();
if (string.IsNullOrWhiteSpace(token)) return;
await GetClaims(token);
}
private async Task<string> GetToken()
{
var response = "";
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
//var tokenClient = new TokenClient(disco.TokenEndpoint, "EduOne", "secret");
//var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api");
var tokenClient = new TokenClient(disco.TokenEndpoint, "ro.client", "secret");
var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("alice@mail.com", "Password1!", "api1");
// var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("alice@mail.com", "Password1!", "openid");
if (tokenResponse.IsError)
{
Console.Out.WriteLine("Error:");
Console.Out.WriteLine(tokenResponse.Error);
Console.Out.Write(tokenResponse.ErrorDescription);
}
else
{
var extraClaims = new UserInfoClient(disco.UserInfoEndpoint);
var identityClaims = await extraClaims.GetAsync(tokenResponse.AccessToken);
response = tokenResponse.Json.ToString();
Console.Out.WriteLine($"token: {response}");
}
return response;
}
private async Task GetClaims(string token)
{
try
{
var obj = JObject.Parse(token);
var tok = obj["access_token"]?.ToString();
_client = new HttpClient();
_client.SetBearerToken(tok);
var response = await _client.GetAsync("http://localhost:5000/api/v1/identity");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
}
}
catch (Exception e)
{
var m = e.Message;
//throw;
}
}
~TestAuthentication()
{
_client = null;
}
}
设置代码:
客户端=&gt;
new Client
{
ClientId = "ro.client",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = {"api1" },
AccessTokenType = AccessTokenType.Reference
},
用户=&gt;
new TestUser
{
SubjectId = "1",
Username = "alice@mail.com",
Password = "Password1!",
Claims =
{
new Claim(JwtClaimTypes.Email, "mail@mail.com")
}
},
资源=&gt;
new IdentityResource("api1", new string[]{JwtClaimTypes.Email})
Startup =&gt;
app.UseIdentityServer();
// app.UseIdentity();
// app.UseIdentity();
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
ApiSecret = "secret",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
DiscoveryDocumentRefreshInterval = TimeSpan.FromMinutes(5),
ApiName = "FiserOpenIdentityApi",
SupportedTokens = IdentityServer4.AccessTokenValidation.SupportedTokens.Both,
AllowedScopes = { "openid", "profile", "email", "api1", "FiserOpenIdentityApi" }
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = "http://localhost:5000",
ClientId = "ro.client",
RequireHttpsMetadata = false,
ClientSecret = "secret",
SaveTokens = false
});
// app.UseJwtBearerAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "RESTApiV1",
template: "api/v1/{controller}/{action}/{id?}");
});
app.UseMongoDbForIdentityServer();
答案 0 :(得分:0)
我正在使用混合流。我认为您在HttpClient中缺少authenticationHeader。 请遵循以下代码,它的工作原理可能会对您有所帮助。
var client = new HttpClient();
var accessToken = await HttpContext
.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);
var disco = await client.GetDiscoveryDocumentAsync("https://localhost:44323");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await client.GetUserInfoAsync(new UserInfoRequest
{
Address = disco.UserInfoEndpoint,
Token = accessToken
});
var address = response.Claims.FirstOrDefault(c => c.Type == "address")?.Value;
var add = new AddressViewModel();
add.Address = address;
return View(add);