好的,所以这个非常令人沮丧,我似乎无法弄清楚如何修复它,希望有人能指出我正确的方向。
因此,如果我可能会破坏架构:
解决方案
问题
尝试访问已通过IdentityServer验证的用户时,它始终返回false
if (this.User.Identity.IsAuthenticated)
{
var identity = this.User.Identity as ClaimsIdentity;
foreach (var claim in identity.Claims)
{
Debug.Write(claim.Type + " " + claim.Value);
}
}
我花了很多时间试图找出为什么我无权访问该用户。
IdentityServer
public void Configuration(IAppBuilder app)
{
app.Map("/identity", idsrvApp =>
{
var idServerServiceFactory = new IdentityServerServiceFactory()
.UseInMemoryClients(Clients.Get())
.UseInMemoryScopes(Scopes.Get())
.UseInMemoryUsers(Users.Get());
var options = new IdentityServerOptions
{
Factory = idServerServiceFactory,
SiteName = "Proderty Security Token Service",
IssuerUri = "https://localhost:44300/identity",
PublicOrigin = "https://localhost:44300/",
SigningCertificate = LoadCertificate()
};
idsrvApp.UseIdentityServer(options);
});
}
public static IEnumerable<Client> Get()
{
return new[]
{
new Client()
{
ClientId = "prodertyclientcredentials",
ClientName = "Proderty (Client Credentials)",
Flow = Flows.ClientCredentials,
ClientSecrets = new List<Secret>()
{
new Secret("Some Secret here".Sha256())
},
AllowAccessToAllScopes = true
},
new Client()
{
ClientId = "prodertyauthcode",
ClientName = "Proderty (Authorization Code)",
Flow = Flows.AuthorizationCode,
RedirectUris = new List<string>()
{
"http://localhost:10765/prodertycallback"
},
ClientSecrets = new List<Secret>()
{
new Secret("Some Secret here".Sha256())
},
AllowAccessToAllScopes = true
},
new Client()
{
ClientId = "prodertyhybrid",
ClientName = "Proderty (Hybrid)",
Flow = Flows.Hybrid,
RedirectUris = new List<string>()
{
"http://localhost:10765"
},
AllowAccessToAllScopes = true
}
};
}
public static IEnumerable<Scope> Get()
{
return new List<Scope>()
{
new Scope
{
Name = "prodertymanagment",
DisplayName = "Proderty Management",
Description = "Allow the application to manage proderty on your behalf.",
Type = ScopeType.Resource
},
StandardScopes.OpenId,
StandardScopes.Profile
};
}
return new List<InMemoryUser>()
{
new InMemoryUser()
{
Username = "Terry",
Password = "Bob",
Subject = "b053d546-6ca8-b95c-77e94d705ddf",
Claims = new[]
{
new Claim(Constants.ClaimTypes.GivenName, "Terry"),
new Claim(Constants.ClaimTypes.FamilyName, "Wingfield")
}
},
new InMemoryUser()
{
Username = "John",
Password = "Bob",
Subject = "bb61e881-3a49-8b62-c13dbe102018",
Claims = new[]
{
new Claim(Constants.ClaimTypes.GivenName, "John"),
new Claim(Constants.ClaimTypes.FamilyName, "Borris")
}
}
};
正如您所看到的,IdentityServer似乎完好无损。一旦调用,我希望我应该访问MVC客户端上的用户。
的WebAPI
public void Configuration(IAppBuilder app)
{
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://localhost:44300/identity",
RequiredScopes = new[] { "prodertymanagment" }
});
}
[Authorize]
public class TestController : ApiController
{
// GET api/<controller>
public string GetOne()
{
return "If you can see this, then we must be authorized! - GETONE - Coming From Test Controller";
}}
}
MVCClient
public static HttpClient GetClient()
{
var client = new HttpClient();
var accessToken = Token.RequestAccessTokenAuthorizationCode();
if (accessToken != null)
{
client.SetBearerToken(accessToken);
}
client.BaseAddress = new Uri("https://localhost:44301/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
return client;
}
public static string RequestAccessTokenAuthorizationCode()
{
var cookie = HttpContext.Current.Request.Cookies.Get("ProdertyCookie");
if (cookie != null && cookie["access_token"] != null)
{
return cookie["access_token"];
}
var authorizeRequest = new IdentityModel.Client.AuthorizeRequest(
"https://localhost:44300/identity/connect/authorize"
);
var state = HttpContext.Current.Request.Url.OriginalString;
var url = authorizeRequest.CreateAuthorizeUrl(
"prodertyauthcode",
"code",
"prodertymanagment",
"http://localhost:10765/prodertycallback",
state);
HttpContext.Current.Response.Redirect(url);
return null;
}
// GET: ProdertyCallback
public async Task<ActionResult> Index()
{
var authCode = Request.QueryString["code"];
var client = new TokenClient(
"https://localhost:44300/identity/connect/token",
"prodertyauthcode",
"Some Secret here"
);
var tokenResponse = await client.RequestAuthorizationCodeAsync(
authCode,
"http://localhost:10765/prodertycallback"
);
Response.Cookies["ProdertyCookie"]["access_token"] = tokenResponse.AccessToken;
return Redirect(Request.QueryString["state"]);
}
使用上面的代码一切正常,如果没有登录我被推送到IdentityServer登录页面,我的回调会触发,然后返回到原始页面。我也有一个访问令牌。
现在我已授权访问该页面,我希望能够访问该用户,但我不会感到非常沮丧。
我非常清楚它是经过身份验证的应用,但我确定其目的是访问经过身份验证的用户(作为客户端的用户)\ n \ n系统也是如此。
public async Task<ActionResult> Index()
{
if (this.User.Identity.IsAuthenticated)
{
var identity = this.User.Identity as ClaimsIdentity;
foreach (var claim in identity.Claims)
{
Debug.Write(claim.Type + " " + claim.Value);
}
}
var httpClient = ProdertyHttpClient.GetClient();
var test = await httpClient.GetAsync("api/test/getone").ConfigureAwait(false);
if (test.IsSuccessStatusCode)
{
var stringContent = await test.Content.ReadAsStringAsync().ConfigureAwait(false);
return Content(stringContent);
}
else
{
return Content(ExceptionHelper.GetExceptionFromResponse(test).ToString());
}
}
唯一想到的是使用Authorize Attribute
尝试使用我尚未安装的核心asp.net identity model
,因为我将拥有自定义数据存储。
任何帮助都非常感谢!