为什么 Context.User.Identity.Name 在 Xamarin 中是空的?
Why Context.User.Identity.Name is empty from Xamarin?
我无法弄清楚为什么当我尝试从 Xamarin 连接时 Context.User.Indetity.Name 是空的。我需要做什么特别的事情吗?我登录到服务器,用户建立了连接。之后我使用以下代码:
var Connection = new HubConnection(Url);
_hub = Connection.CreateHubProxy(hubName);
_hub.On(srvEvent, onData);
await Connection.Start();
但我从来没有得到用户名。我做错了什么?
这是服务器的代码:
var name = Context.User.Identity.Name;
Connections.Add(name, Context.ConnectionId);
return base.OnConnected();
当它来自 Web 应用程序而不是来自 xamarin 应用程序时它有效。
谢谢!
这是我告诉你的代码。
我正在使用外部 OAuth2 服务器进行身份验证,因此我必须以某种方式将访问令牌传递给 SignalR,因为 SignalR 使用 Web 套接字来回传递消息,所以我无法在 header 因为网络套接字不支持。
我正在以这种方式将该访问令牌作为查询字符串参数传递(Javascript 客户端)
$.connection.hub.qs = "access_token=" + mytoken;
然后在我的 SignalR 上我添加了一个中间件,该中间件获取该查询字符串并将其添加到 header 作为使用 Bearer Token 的授权 header。这是在我的启动 class
中以这种方式完成的
app.UseAuthQSTokenExtractor();
中间件的代码就是这个
namespace Owin
{
public static class AuthorizationQSTokenExtractorExtension
{
public static void UseAuthQSTokenExtractor(this IAppBuilder app)
{
app.Use<AuthorizationQsTokenExtractorMiddleware>();
}
}
}
namespace Chat.Middleware
{
public class AuthorizationQsTokenExtractorMiddleware : OwinMiddleware
{
public AuthorizationQsTokenExtractorMiddleware(OwinMiddleware next)
: base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
Debug.WriteLine("signalr-auth-middleware");
string bearerToken = context.Request.Query.Get("access_token");
Debug.WriteLine("signar-bearer: " + bearerToken);
if (bearerToken != null)
{
TokenHelper.DecodeAndWrite(bearerToken);
string[] authorization = { "Bearer " + bearerToken };
context.Request.Headers.Add("Authorization", authorization);
}
await Next.Invoke(context);
}
}
我的创业公司 class 看起来像这样
app.UseCors(CorsOptions.AllowAll);
app.UseAuthQSTokenExtractor();
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = ConfigurationManager.AppSettings["api:idserver"],
RequiredScopes = new[]
{
"chat-hub"
}
});
var hubConfiguration = new HubConfiguration ();
hubConfiguration.EnableDetailedErrors = true;
app.RunSignalR(hubConfiguration);
你可以在上面的代码中看到我告诉 SignalR 使用 Oauth2 服务器的代码,就是这个代码
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = ConfigurationManager.AppSettings["api:idserver"],
RequiredScopes = new[]
{
"chat-hub"
}
});
完成所有这些设置后,我可以访问我的 Context.User.Identity.Name,如果你想获得其他 IdentityClaim,你可以这样做
var identity = Context.User.Identity as ClaimsIdentity;
我正在使用上面的代码来获取 subjectId (userid),就像这样
public static string[] GetIdentityClaimsIssSub(HubCallerContext Context)
{
var identity = Context.User.Identity as ClaimsIdentity;
if (identity == null)
return null;
var issuerFromIdentity = identity.FindFirst("iss");
var subFromIdentity = identity.FindFirst("sub");
if (issuerFromIdentity == null || subFromIdentity == null)
return null;
return new string[] { issuerFromIdentity.Value, subFromIdentity.Value };
}
希望对你有帮助
我无法弄清楚为什么当我尝试从 Xamarin 连接时 Context.User.Indetity.Name 是空的。我需要做什么特别的事情吗?我登录到服务器,用户建立了连接。之后我使用以下代码:
var Connection = new HubConnection(Url);
_hub = Connection.CreateHubProxy(hubName);
_hub.On(srvEvent, onData);
await Connection.Start();
但我从来没有得到用户名。我做错了什么?
这是服务器的代码:
var name = Context.User.Identity.Name;
Connections.Add(name, Context.ConnectionId);
return base.OnConnected();
当它来自 Web 应用程序而不是来自 xamarin 应用程序时它有效。
谢谢!
这是我告诉你的代码。
我正在使用外部 OAuth2 服务器进行身份验证,因此我必须以某种方式将访问令牌传递给 SignalR,因为 SignalR 使用 Web 套接字来回传递消息,所以我无法在 header 因为网络套接字不支持。
我正在以这种方式将该访问令牌作为查询字符串参数传递(Javascript 客户端)
$.connection.hub.qs = "access_token=" + mytoken;
然后在我的 SignalR 上我添加了一个中间件,该中间件获取该查询字符串并将其添加到 header 作为使用 Bearer Token 的授权 header。这是在我的启动 class
中以这种方式完成的app.UseAuthQSTokenExtractor();
中间件的代码就是这个
namespace Owin
{
public static class AuthorizationQSTokenExtractorExtension
{
public static void UseAuthQSTokenExtractor(this IAppBuilder app)
{
app.Use<AuthorizationQsTokenExtractorMiddleware>();
}
}
}
namespace Chat.Middleware
{
public class AuthorizationQsTokenExtractorMiddleware : OwinMiddleware
{
public AuthorizationQsTokenExtractorMiddleware(OwinMiddleware next)
: base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
Debug.WriteLine("signalr-auth-middleware");
string bearerToken = context.Request.Query.Get("access_token");
Debug.WriteLine("signar-bearer: " + bearerToken);
if (bearerToken != null)
{
TokenHelper.DecodeAndWrite(bearerToken);
string[] authorization = { "Bearer " + bearerToken };
context.Request.Headers.Add("Authorization", authorization);
}
await Next.Invoke(context);
}
}
我的创业公司 class 看起来像这样
app.UseCors(CorsOptions.AllowAll);
app.UseAuthQSTokenExtractor();
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = ConfigurationManager.AppSettings["api:idserver"],
RequiredScopes = new[]
{
"chat-hub"
}
});
var hubConfiguration = new HubConfiguration ();
hubConfiguration.EnableDetailedErrors = true;
app.RunSignalR(hubConfiguration);
你可以在上面的代码中看到我告诉 SignalR 使用 Oauth2 服务器的代码,就是这个代码
app.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = ConfigurationManager.AppSettings["api:idserver"],
RequiredScopes = new[]
{
"chat-hub"
}
});
完成所有这些设置后,我可以访问我的 Context.User.Identity.Name,如果你想获得其他 IdentityClaim,你可以这样做
var identity = Context.User.Identity as ClaimsIdentity;
我正在使用上面的代码来获取 subjectId (userid),就像这样
public static string[] GetIdentityClaimsIssSub(HubCallerContext Context)
{
var identity = Context.User.Identity as ClaimsIdentity;
if (identity == null)
return null;
var issuerFromIdentity = identity.FindFirst("iss");
var subFromIdentity = identity.FindFirst("sub");
if (issuerFromIdentity == null || subFromIdentity == null)
return null;
return new string[] { issuerFromIdentity.Value, subFromIdentity.Value };
}
希望对你有帮助