使用令牌 c# 的安全 Web API
Secure Web API with token c#
我用 Cordova 创建了一个移动应用程序,有 2 种登录方法 Facebook 和 Google。我验证令牌(FB 或 Google)后,我想使用其中之一来保护我的 Web API 2 并与我的应用程序通信,但我不知道将它存储在何处web API,我将其保存到 Thread.CurrentPrincipal,但后来 returns 为空。
这是我的代码:
public bool UserExist(Credentials credentials,ISQLDB socialDB,IEncrypt encrypt)
{
bool exist = false;
//IPrincipal principal;
if (credentials.fb_access_Token != "")
exist =CheckFB(credentials.fb_access_Token);
else if (credentials.Google_token != "")
exist= CheckGoogle(credentials.Google_token);
if(exist==true)
{
var identity = new GenericIdentity(credentials.Token);
SetPrincipal(new GenericPrincipal(identity, null));
return true;
}
else
return false;
}
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
Web API 安全对我来说是一件复杂的事情,我不知道为什么,所以我感谢你的帮助。
我为令牌使用自定义中间件,如下所示:
public class TokenAuthenticationOptions : AuthenticationSchemeOptions
{
}
public class TokenAuthentication : AuthenticationHandler<TokenAuthenticationOptions>
{
public const string SchemeName = "TokenAuth";
public TokenAuthentication(IOptionsMonitor<TokenAuthenticationOptions> options,
ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock)
{
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
return Task.Run(() => Authenticate());
}
private AuthenticateResult Authenticate()
{
string token = Context.Request.Query["token"];
if (token == null) return AuthenticateResult.Fail("No JWT token provided");
try
{
var principal = LoginControl.Validate(token);
return AuthenticateResult.Success(new AuthenticationTicket(principal, SchemeName));
}
catch (Exception)
{
return AuthenticateResult.Fail("Failed to validate token");
}
}
}
方便修改。然后你可以在你的启动中使用这个:
services.AddAuthentication(TokenAuthentication.SchemeName)
.AddScheme<TokenAuthenticationOptions, TokenAuthentication>
(TokenAuthentication.SchemeName, o => { });
你不能 "save the token",因为 API 是无状态的,这意味着(除其他外)不应该跟踪正在调用的客户端及其相应的身份验证令牌(会话)。
也就是说,您每次都需要传递令牌,并在 OWIN 管道中定义一个授权中间件,以验证发送的令牌。这是使用 IdentityServer
的示例
public void Configuration(IAppBuilder app)
{
// accept access tokens from identityserver and require a scope of 'api1'
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "http://localhost:5000",
ValidationMode = ValidationMode.ValidationEndpoint,
RequiredScopes = new[] { "api1" }
});
// configure web api
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
// require authentication for all controllers
config.Filters.Add(new AuthorizeAttribute());
app.UseWebApi(config);
}
来自 MS Docs
的其他示例
public void ConfigureAuth(IAppBuilder app)
{
// Enable the application to use cookies to authenticate users
app.UseCookieAuthentication(CookieOptions);
// Enable the application to use a cookie to store temporary information about a user logging in with a third party login provider
app.UseExternalSignInCookie(ExternalCookieAuthenticationType);
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions, ExternalOAuthAuthenticationType);
// Uncomment the following lines to enable logging in with third party login providers
//app.UseMicrosoftAccountAuthentication(
// clientId: "",
// clientSecret: "");
//app.UseTwitterAuthentication(
// consumerKey: "",
// consumerSecret: "");
//app.UseFacebookAuthentication(
// appId: "",
// appSecret: "");
//app.UseGoogleAuthentication();
}
我用 Cordova 创建了一个移动应用程序,有 2 种登录方法 Facebook 和 Google。我验证令牌(FB 或 Google)后,我想使用其中之一来保护我的 Web API 2 并与我的应用程序通信,但我不知道将它存储在何处web API,我将其保存到 Thread.CurrentPrincipal,但后来 returns 为空。
这是我的代码:
public bool UserExist(Credentials credentials,ISQLDB socialDB,IEncrypt encrypt)
{
bool exist = false;
//IPrincipal principal;
if (credentials.fb_access_Token != "")
exist =CheckFB(credentials.fb_access_Token);
else if (credentials.Google_token != "")
exist= CheckGoogle(credentials.Google_token);
if(exist==true)
{
var identity = new GenericIdentity(credentials.Token);
SetPrincipal(new GenericPrincipal(identity, null));
return true;
}
else
return false;
}
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
Web API 安全对我来说是一件复杂的事情,我不知道为什么,所以我感谢你的帮助。
我为令牌使用自定义中间件,如下所示:
public class TokenAuthenticationOptions : AuthenticationSchemeOptions
{
}
public class TokenAuthentication : AuthenticationHandler<TokenAuthenticationOptions>
{
public const string SchemeName = "TokenAuth";
public TokenAuthentication(IOptionsMonitor<TokenAuthenticationOptions> options,
ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock)
{
}
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
return Task.Run(() => Authenticate());
}
private AuthenticateResult Authenticate()
{
string token = Context.Request.Query["token"];
if (token == null) return AuthenticateResult.Fail("No JWT token provided");
try
{
var principal = LoginControl.Validate(token);
return AuthenticateResult.Success(new AuthenticationTicket(principal, SchemeName));
}
catch (Exception)
{
return AuthenticateResult.Fail("Failed to validate token");
}
}
}
方便修改。然后你可以在你的启动中使用这个:
services.AddAuthentication(TokenAuthentication.SchemeName)
.AddScheme<TokenAuthenticationOptions, TokenAuthentication>
(TokenAuthentication.SchemeName, o => { });
你不能 "save the token",因为 API 是无状态的,这意味着(除其他外)不应该跟踪正在调用的客户端及其相应的身份验证令牌(会话)。
也就是说,您每次都需要传递令牌,并在 OWIN 管道中定义一个授权中间件,以验证发送的令牌。这是使用 IdentityServer
的示例public void Configuration(IAppBuilder app)
{
// accept access tokens from identityserver and require a scope of 'api1'
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "http://localhost:5000",
ValidationMode = ValidationMode.ValidationEndpoint,
RequiredScopes = new[] { "api1" }
});
// configure web api
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
// require authentication for all controllers
config.Filters.Add(new AuthorizeAttribute());
app.UseWebApi(config);
}
来自 MS Docs
的其他示例public void ConfigureAuth(IAppBuilder app)
{
// Enable the application to use cookies to authenticate users
app.UseCookieAuthentication(CookieOptions);
// Enable the application to use a cookie to store temporary information about a user logging in with a third party login provider
app.UseExternalSignInCookie(ExternalCookieAuthenticationType);
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions, ExternalOAuthAuthenticationType);
// Uncomment the following lines to enable logging in with third party login providers
//app.UseMicrosoftAccountAuthentication(
// clientId: "",
// clientSecret: "");
//app.UseTwitterAuthentication(
// consumerKey: "",
// consumerSecret: "");
//app.UseFacebookAuthentication(
// appId: "",
// appSecret: "");
//app.UseGoogleAuthentication();
}